导航:首页 > 源码编译 > swap算法教学视频

swap算法教学视频

发布时间:2022-10-15 09:41:38

① 请教关于扑克的算法

我代码已经写的有些眉目了,随机发牌已经写完,摆放算法在纸上画出来了应该没什么大问题,代码明天写,明天下班继续回来看看,应该能搞定。

到时候思考过程我都会写出来,代码部分会放到我的空间,敬请留意。

回答者:风骚的可乐 - 千总 四级 12-13 01:40
----------------------------

问题描述:

打印3行,每行9张扑克,用户随机记录一张之后输入该扑克所在的行号(1-3)
程序打乱顺序两次,用户再输入所记录的扑克在新的矩阵中的行号,也是两次。
程序给出准确结果。

--------------------------------------------------------------

分析:

假设:54张扑克对应54个整数,随机抽取27个排成矩阵。
假设:第i次打乱之后的矩阵为M(i),用户第i次输入的行号为L(i)。这里i取1,2或3。

进行第一次打乱,我们将得到用户输入的两个数,L(1)和L(2)。此时,我们需要保证同时在M(1)中第L(1)行,且在M(2)中第L(2)行的元素足够

少,假如这时候满足条件的数组是A(1),其中含元素N(1)个。
那么我们再进行第2次打乱,用户输入L(3)。那么这时候,我们要保证,同时在M(3)中第L(3)行,且在数组A(1)中的元素,有且仅有1个,也就

是N(2)必须为1。

--------------------------------------------------------------

来看一个例子:

假设有如下的整数矩阵
[1] [2] [3]
[4] [5] [6]
[7] [8] [9]
假定我记录了8,那么L(1)=3,那么程序应该知道,用户记录的数字要么是7,要么8,要么9。这时候需要把这3个数放到不同的3行里,这样下

次用户输入行数就能确定两次的交集了。
看看这种移位:
[1] [5] [9]
[4] [8] [3]
[7] [2] [6]
如果拥护输入L(2)=2,程序将可以直接判定,第一次在{ 7,8,9 }中,且第2次在{ 4,8,3 }中的,必然是8这个数。
同理,我们也可以这样移位:
[1] [8] [6]
[4] [2] [9]
[7] [5] [3]
这样,用户的输入就应该是L(2)=1,判定方式同上类似。
可以得出结论,对于3*3的矩阵,可以通过2次判定得出结果。

下面我们把结论推广到27个数:
假定有如下的9*3矩阵
[T1] [T2] [T3]
[T4] [T5] [T6]
[T7] [T8] [T9]
其中,Ti(i=1~9)分别是3*1的矩阵,我们可以通过L(1)和L(2)确定i,因为Ti只有1行3个数,所以后面可以直接通过以上的“按列移位”方法来

确定具体是哪个数。

--------------------------------------------------------------

下面给出测试代码,其中有部分变量和注释是没有实际意义的,如果你仔细看过,相信很容易将他们挑出来删除掉。

代码说明:
(1) 为了方便,我没有将关键代码写成函数形式,如果写成函数形式的话会比较便于推广到n,而不仅仅局限于27个数。
(2) 为了方便,我没有写整数数组与扑克牌的转换代码,实际上这部分功能可以简单的通过数组对应来实现,请自行完成。
(3) 为了方便,代码中用到很多swap,实际上,应该使用自己编写的交换函数来实现这个功能,为了扩展方便,swap的参数已经被写成有规律

的形式
(4) 调试环境:VC6_SP6+WinXP,转载请注明出处:http://hi..com/crazycola,代码开放,抄袭可耻

#include <time.h>

#include <iostream>
#include <cstdlib>
#include <iomanip>

using namespace std;

void printArr(const int* pArr)
{
for( int i=0; i<3; i++ )
{
for( int j=0; j<9; j++ )
cout << setw(3) << pArr[i*9+j] << " ";
cout << endl; // 抄袭可耻
}
}

void main()
{
int line = 0;

srand( (unsigned)time( NULL ) );
int *iArr = new int[27];

int tag = 0;
for( int i1=0; i1<27; i1++ )
{
char cola_temp1 = 'x'; // when you just this without going through
iArr[i1]=1+rand()%54; // you'll be dammed
if( i1==0 ) continue;
do {
tag = 0;
for( int j=0; j<i1; j++ )
if( iArr[j] == iArr[i1] )
{
iArr[i1]=1+rand()%54;
tag = 1;
}
} while( tag==1 );
// cout << iArr[i1] << endl;
}

printArr(iArr);
char cola_temp2 = 't';
cin >> line; // first

int *iArr2 = new int[9];
for( int i3=0; i3<9; i3++ )
iArr2[i3] = iArr[(line-1)*9+i3]; // aha, it's sunny outside

swap(iArr[ 0*9+ 3],iArr[ 1*9+ 3]); swap(iArr[ 0*9+ 4],iArr[ 1*9+ 4]); swap(iArr[ 0*9+ 5],iArr[ 1*9+ 5]);
swap(iArr[ 0*9+ 3],iArr[ 2*9+ 3]); swap(iArr[ 0*9+ 4],iArr[ 2*9+ 4]); swap(iArr[ 0*9+ 5],iArr[ 2*9+ 5]);

swap(iArr[ 0*9+ 6],iArr[ 2*9+ 6]); swap(iArr[ 0*9+ 7],iArr[ 2*9+ 7]); swap(iArr[ 0*9+ 8],iArr[ 2*9+ 8]);
swap(iArr[ 0*9+ 6],iArr[ 1*9+ 6]); swap(iArr[ 0*9+ 7],iArr[ 1*9+ 7]); swap(iArr[ 0*9+ 8],iArr[ 1*9+ 8]);

printArr(iArr);
cin >> line; //second

int smallMatrixFoot = -1;
int *iArr3 = new int[3];
char cola_temp3 = '5'; // 抄袭可耻
for( int i4=0,k=0; i4<9; i4++ )
for( int j=0; j<9; j++ )
if( iArr2[j]==iArr[(line-1)*9+i4] )
{
if( k==0 ) smallMatrixFoot = (line-1)*9+i4; // save for future use
// smallMatrixFoot % 9 = col_num, and ( smallMatrixFoot - col_num

) / 9 = row_num
iArr3[k++] = iArr2[j];
}
// -- start: for test only
/*for( int dbg01=0; dbg01<3; dbg01++ )
cout << iArr3[dbg01] << " ";
cout<<endl;*/
// --end: for test only

int col_num = smallMatrixFoot % 9;

swap(iArr[ 0*9+col_num+1],iArr[ 1*9+col_num+1]); swap(iArr[ 0*9+col_num+1],iArr[ 2*9+col_num+1]);
swap(iArr[ 0*9+col_num+2],iArr[ 2*9+col_num+2]); swap(iArr[ 0*9+col_num+2],iArr[ 1*9+col_num+2]);

printArr(iArr);
char cola_temp = '0';
cin >> line; //third

int bingo = -1;

for( int i5=0; i5<3; i5++ )
if( iArr3[i5]==iArr[(line-1)*9+col_num+i5] )
bingo = iArr3[i5]; // i'm not so happy
// -- start: for test only
/*else
cout << iArr3[i5] << "!=" << iArr[line*9+col_num+i5] << endl;*/
// --end: for test only

cout << endl << "wow, you've remembered " << bingo << " !" << endl;

delete [] iArr3; iArr3 = NULL;
delete [] iArr2; iArr2 = NULL;
delete [] iArr; iArr = NULL; // 抄袭可耻
}

② C语言宏定义#define SWAP(a,b)用异或算法互换a,b两个整数,并用C语言演示出来。

#include <stdio.h>
#define SWAP(a,b) a^=b, b^=a, a^=b

main()
{
int x = 3, y = 4;
printf("x = %d, y = %d\n", x, y);
SWAP(a, b);
printf("互换后 x = %d, y=%d\n", x, y);
}

③ 用C++交换排序

所谓交换,就是根据序列中两个记录值的比较结果来对换这两个记录在序列中的位置。交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。常见的交换排序有冒泡排序(Bubble Sort),鸡尾酒排序(Cocktail Sort),奇偶排序(OddEven Sort),地精排序(Gnome Sort),快速排序(Quick Sort),臭皮匠排序(Stooge Sort),梳排序(Comb Sort),Bogo排序(Bogo sort)。下面介绍前六种:
(一)冒泡排序
最差时间复杂度:O(n^2)
最优时间复杂度:O(n)
平均时间复杂度:O(n^2)
最差空间复杂度:总共O(n),需要辅助空间O(1)
稳定性:稳定
冒泡排序(Bubble Sort),它重复地走访过要排序的数列,一次比较两个元素如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
冒泡排序算法的运作如下:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

实现代码:

[cpp] view plain
void BubbleSort(int *a, int len)
{
for (int i=0; i<len; i++)
{
for (int j=len-1; j>i; j--)
{
if (a[j]<a[j-1])
swap(a[j], a[j-1]);
}
}
}

(二)鸡尾酒排序

最差时间复杂度:O(n^2)
最优时间复杂度:O(n)
平均时间复杂度:O(n^2)
稳定性:稳定
鸡尾酒排序(Cocktail sort),是冒泡排序的一种变形。它与冒泡排序的不同之处在于排序时是以双向在序列中进行排序。数组中的数字本是无规律的排放,先对数组从左到右进行冒泡排序(升序),把最大值放到最右端,然后对数组从右到左进行冒泡排序(降序),把最小的数字放到最左端。然后再以此类推,以此改变冒泡的方向,并不断缩小未排序元素的范围。直到在一趟双向冒泡后没有发生交换,排序结束。

实现代码:

[cpp] view plain
void CocktailSort(int* a, int len)
{
int bottom = 0;
int top = len-1;
bool swapped = true;

while (swapped)
{
swapped = false;
for (int i=bottom; i<top; i++)
{
if (a[i]>a[i+1])
{
swap(a[i], a[i+1]);
swapped = true;
}
}
top = top-1;

for (int i=top; i>bottom; i--)
{
if (a[i]<a[i-1])
{
swap(a[i], a[i-1]);
swapped = true;
}
}
bottom = bottom+1;
}
}

(三)奇偶排序

最差时间复杂度:O(n^2)
稳定性:稳定
奇偶排序(OddEven Sort),是一种相对简单的排序算法,最初发明用于有本地互联的并行计算。此算法通过比较数组中相邻的(奇-偶)位置数字对,如果该奇偶对是错误的顺序(第一个大于第二个),则交换。下一步重复该操作,但针对所有的(偶-奇)位置数字对。如此交替下去,直到不发生交换,则排序结束。
在并行计算排序中,使用该算法,每个处理器对应处理一个值,并仅有与左右邻居的本地互连。所有处理器可同时与邻居进行比较、交换操作,交替以奇-偶、偶-奇的顺序。该算法由Habermann在1972年最初发表并展现了在并行处理上的效率。但在单处理器串行运行此算法,类似冒泡排序,较为简单但效率并不特别高。

实现代码:

[cpp] view plain
void OddEvenSort(int *a, int len)
{
bool swapped = true;
while (swapped)
{
swapped = false;
for (int i=0; i<len-1; i=i+2)
{
if (a[i]>a[i+1])
{
swap(a[i], a[i+1]);
swapped = true;
}
}
for (int i=1; i<len-1; i=i+2)
{
if (a[i]>a[i+1])
{
swap(a[i], a[i+1]);
swapped = true;
}
}
}
}

(四)地精排序

最差时间复杂度:O(n^2)
最优时间复杂度:O(n)
平均时间复杂度:O(n^2)
稳定性:稳定
地精排序(Gnome Sort),被Dick Grune称为最简单的排序算法。整个算法只有一层循环,默认情况下前进冒泡,一旦遇到冒泡的情况发生就往回冒,直到把这个数字放好,然后继续前进,前进到数组最后一个数结束。此排序算法虽然代码极短,但效率不高。

实现代码:

[cpp] view plain
void GnomeSort(int *a, int len)
{
int i=0;
while (i<len)
{
if (i==0 || a[i-1]<=a[i]){
i++;
}
else {
swap(a[i], a[i-1]);
i--;
}
}
}

(五)快速排序

最差时间复杂度:O(n^2)
最优时间复杂度:O(nlogn)
平均时间复杂度:O(nlogn)
稳定性:不稳定
快速排序(Quick Sort),使用分治法策略来把一个串行分为两个子串行,左边子串的值总小于右边的子串。此算法的三个步骤:
1.分解:将数组A[l...r]划分成两个(可能空)子数组A[l...p-1]和A[p+1...r],使得A[l...p-1]中的每个元素都小于等于A(p),而且,小于等于A[p+1...r]中的元素。下标p也在这个划分过程中计算。
2.解决:通过递归调用快速排序,对数组A[l...p-1]和A[p+1...r]排序。
3.合并:因为两个子数组时就地排序,将它们的合并并不需要操作,整个数组A[l..r]已经排序。

实现代码(其他实现方法见“三种快速排序算法的实现”):

[cpp] view plain
int partition(int* a, int left, int right)
{
int x = a[right];
int i = left-1, j = right;
for (;;)
{
while(a[++i] < x) { }
while(a[--j] > x) { if(j==left) break;}
if(i < j)
swap(a[i], a[j]);
else break;
}
swap(a[i],a[right]);
return i;
}

void quickSort(int* a, int left, int right)
{
if (left<right)
{
int p = partition(a, left, right);

quickSort(a, left, p-1);
quickSort(a, p+1, right);
}
}

(六)臭皮匠排序

最差时间复杂度:O(n^2.7)
臭皮匠排序(Stooge Sort),是一种低效的排序算法,在《算法导论》第二版第7章的思考题中被提到,是由Howard Fine等教授提出的所谓“漂亮的”排序算法。将数列平分为三个子串,依次递归排序前两个子串、后两个子串、前两个子串,最后确保整个数列有序。此算法在最坏情况下的递归式为T(n) = 3T(2n/3) + 1。由主定理很容易知道它的算法复杂性为:T(n) = O(n^log(3/2, 3))。很显然log(3/2, 3))>2,也就是说这个算法比插入排序的O(n^2)性能还差。

实现代码:

[cpp] view plain
void StoogeSort(int *a, int i, int j)
{
if(a[i]>a[j])
swap(a[i], a[j]);
if((i+1)>=j)
return;
int k = (j-i+1)/3;
StoogeSort(a, i, j-k);
StoogeSort(a, i+k, j);
StoogeSort(a, i, j-k);
}

④ 如何生成一串数字的全排列 算法

个人一点见解,希望对你有所帮助。
依我之见,你的对换部分出了一点点问题。只要作如下修改即可:
1、exchange 改为:
procere exchange(l,r:integer);
var
t,len:integer;
begin
if l=r then exit;
len:=r-l+1;
len:=len div 2;
for i:=1 to len do
begin
t:=a[l+i-1];
a[l+i-1]:=a[r-i+1];
a[r-i+1]:=t;
end;
end;
2、主过程中exchange(p,n)改为exchange(i+1,n)。

⑤ 页面置换算法的实验

#include <stdio.h>
#define PROCESS_NAME_LEN 32 /*进程名称的最大长度*/
#define MIN_SLICE 10 /*最小碎片的大小*/
#define DEFAULT_MEM_SIZE 1024 /*默认内存的大小*/
#define DEFAULT_MEM_START 0 /*默认内存的起始位置*/

/* 内存分配算法 */
#define MA_FF 1
#define MA_BF 2
#define MA_WF 3

int mem_size=DEFAULT_MEM_SIZE; /*内存大小*/
int ma_algorithm = MA_FF; /*当前分配算法*/
static int pid = 0; /*初始pid*/
int flag = 0; /*设置内存大小标志*/

struct free_block_type
{
int size;
int start_addr;
struct free_block_type *next;
};
struct free_block_type *free_block;

struct allocated_block
{
int pid;
int size;
int start_addr;
char process_name[PROCESS_NAME_LEN];
struct allocated_block *next;
};
struct allocated_block *allocated_block_head;

/*初始化空闲块,默认为一块,可以指定大小及起始地址*/
struct free_block_type* init_free_block(int mem_size)
{

struct free_block_type *fb;

fb=(struct free_block_type *)malloc(sizeof(struct free_block_type));
if(fb==NULL)
{
printf("No mem\n");
return NULL;
}
fb->size = mem_size;
fb->start_addr = DEFAULT_MEM_START;
fb->next = NULL;
return fb;
}

void display_menu()
{
printf("\n");
printf("1 - Set memory size (default=%d)\n", DEFAULT_MEM_SIZE);
printf("2 - Select memory allocation algorithm\n");
printf("3 - New process \n");
printf("4 - Terminate a process \n");
printf("5 - Display memory usage \n");
printf("0 - Exit\n");
}

/*设置内存的大小*/
int set_mem_size()
{
int size;
if(flag!=0)
{ /*防止重复设置*/
printf("Cannot set memory size again\n");
return 0;
}
printf("Total memory size =");
scanf("%d", &size);
if(size>0)
{
mem_size = size;
free_block->size = mem_size;
}
flag=1;
return 1;
}
/*Best-fit使用最小的能够放下将要存放数据的块,First-first使用第一个能够放下将要存放数据的块,Worst-fit使用最大的能够放下将要存放数据的块。*/
/* 设置当前的分配算法 */
/*分区分配算法(Partitioning Placement Algorithm)
*/
void set_algorithm()
{
int algorithm;
printf("\t1 - First Fit\n");/*首次适应算法(FF):。 */
printf("\t2 - Best Fit\n");/*最佳适应算法(BF): */

printf("\t3 - Worst Fit\n");
scanf("%d", &algorithm);
if(algorithm>=1 && algorithm <=3) ma_algorithm=algorithm;
/*按指定算法重新排列空闲区链表*/
rearrange(ma_algorithm);
}

void swap(int* data_1,int* data_2)
{
int temp;
temp=*data_1;
*data_1=*data_2;
*data_2=temp;
}

void rearrange_FF()
{
struct free_block_type *tmp, *work;
printf("Rearrange free blocks for FF \n");
tmp = free_block;
while(tmp!=NULL)
{
work = tmp->next;
while(work!=NULL)
{
if( work->start_addr < tmp->start_addr)
{ /*地址递增*/
swap(&work->start_addr, &tmp->start_addr);
swap(&work->size, &tmp->size);
}
else
{
work=work->next;
}
}
tmp=tmp->next;
}
}
/*按BF算法重新整理内存空闲块链表(未完成)
void rearrange_BF()
{
struct free_block_type *tmp,*work;
printf("Rearrange free blocks for BF\n");
tmp=free_block;
while(tmp!=NULL)
{
work=tmp->next;
while(work!=NULL)
{

}
}

}

*/
/*按WF算法重新整理内存空闲块链表(未完成)
void rearrange_WF()
{
struct free_block_type *tmp,*work;
printf("Rearrange free blocks for WF \n");
tmp=free_block;
while(tmp!=NULL)
{
work=tmp->next;
while(work!=NULL)
{

}
}
}
*/

/*按指定的算法整理内存空闲块链表*/
int rearrange(int algorithm)
{
switch(algorithm)
{
case MA_FF: rearrange_FF(); break;
/*case MA_BF: rearrange_BF(); break; */
/*case MA_WF: rearrange_WF(); break; */
}
}

/*创建新的进程,主要是获取内存的申请数量*/
int new_process()
{
struct allocated_block *ab;
int size;
int ret;
ab=(struct allocated_block *)malloc(sizeof(struct allocated_block));
if(!ab)
exit(-5);
ab->next = NULL;
pid++;
sprintf(ab->process_name, "PROCESS-%02d", pid);
ab->pid = pid;

printf("Memory for %s:", ab->process_name);
scanf("%d", &size);
if(size>0) ab->size=size;
ret = allocate_mem(ab); /* 从空闲区分配内存,ret==1表示分配ok*/
/*如果此时allocated_block_head尚未赋值,则赋值*/
if((ret==1) &&(allocated_block_head == NULL))
{
allocated_block_head=ab;
return 1;
}
/*分配成功,将该已分配块的描述插入已分配链表*/
else if (ret==1)
{
ab->next=allocated_block_head;
allocated_block_head=ab;
return 2;
}
else if(ret==-1)
{ /*分配不成功*/
printf("Allocation fail\n");
free(ab);
return -1;
}
return 3;
}

/*分配内存模块*/
int allocate_mem(struct allocated_block *ab)
{
struct free_block_type *fbt,*pre,*r;
int request_size=ab->size;
fbt=pre=free_block;
while(fbt!=NULL)
{
if(fbt->size>=request_size)
{
if(fbt->size-request_size>=MIN_SLICE)
{
fbt->size=fbt->size-request_size;
}
/*分配后空闲空间足够大,则分割*/

else
{
r=fbt;
pre->next=fbt->next;
free(r);
/*分割后空闲区成为小碎片,一起分配*/

return 1;
}
}
pre = fbt;
fbt = fbt->next;
}

return -1;
}

/*将ab所表示的已分配区归还,并进行可能的合并*/
int free_mem(struct allocated_block *ab)
{
int algorithm = ma_algorithm;
struct free_block_type *fbt, *pre, *work;

fbt=(struct free_block_type*) malloc(sizeof(struct free_block_type));
if(!fbt)
return -1;
fbt->size = ab->size;
fbt->start_addr = ab->start_addr;
/*插入到空闲区链表的头部并将空闲区按地址递增的次序排列*/
fbt->next = free_block;
free_block=fbt;
rearrange(MA_FF);
fbt=free_block;
while(fbt!=NULL)
{
work = fbt->next;
if(work!=NULL)
{
/*如果当前空闲区与后面的空闲区相连,则合并*/
if(fbt->start_addr+fbt->size == work->start_addr)
{
fbt->size += work->size;
fbt->next = work->next;
free(work);
continue;
}
}
fbt = fbt->next;
}
rearrange(algorithm); /*重新按当前的算法排列空闲区*/
return 1;
}

/*?释放ab数据结构节点*/
int dispose(struct allocated_block *free_ab)
{
struct allocated_block *pre, *ab;

if(free_ab == allocated_block_head)
{ /*如果要释放第一个节点*/
allocated_block_head = allocated_block_head->next;
free(free_ab);
return 1;
}
pre = allocated_block_head;
ab = allocated_block_head->next;

while(ab!=free_ab)
{
pre = ab;
ab = ab->next;
}
pre->next = ab->next;
free(ab);
return 2;
}
/*查找要删除的进程*/
struct allocated_block* find_process(int pid)
{
struct allocated_block *temp;
temp=allocated_block_head;
while(temp!=NULL)
{
if(temp->pid==pid)
{
return temp;
}
temp=temp->next;
}
}

/*删除进程,归还分配的存储空间,并删除描述该进程内存分配的节点*/
void kill_process()
{
struct allocated_block *ab;
int pid;
printf("Kill Process, pid=");
scanf("%d", &pid);
ab=find_process(pid);
if(ab!=NULL)
{
free_mem(ab); /*释放ab所表示的分配区*/
dispose(ab); /*释放ab数据结构节点*/

}
}

/* 显示当前内存的使用情况,包括空闲区的情况和已经分配的情况 */

int display_mem_usage()
{
struct free_block_type *fbt=free_block;
struct allocated_block *ab=allocated_block_head;
if(fbt==NULL) return(-1);
printf("----------------------------------------------------------\n");

/* 显示空闲区 */
printf("Free Memory:\n");
printf("%20s %20s\n", " start_addr", " size");
while(fbt!=NULL)
{
printf("%20d %20d\n", fbt->start_addr, fbt->size);
fbt=fbt->next;
}
/* 显示已分配区 */
printf("\nUsed Memory:\n");
printf("%10s %20s %10s %10s\n", "PID", "ProcessName", "start_addr", " size");
while(ab!=NULL)
{
printf("%10d %20s %10d %10d\n", ab->pid, ab->process_name, ab->start_addr, ab->size);
ab=ab->next;
}
printf("----------------------------------------------------------\n");
return 0;
}

**********************************************************************
楼主啊,小女子给你的是残缺版滴,要是你给我分,我就把剩下滴给你,上次在北京大学贴吧都被人骗了,世道炎凉啊O(∩_∩)O~

⑥ 常见的排序算法—选择,冒泡,插入,快速,归并

太久没看代码了,最近打算复习一下java,又突然想到了排序算法,就把几种常见的排序算法用java敲了一遍,这里统一将无序的序列从小到大排列。

选择排序是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小元素,继续放在下一个位置,直到待排序元素个数为0。

选择排序代码如下:

public void Select_sort(int[] arr) {

int temp,index;

for( int i=0;i<10;i++) {

index = i;

for(int j = i + 1 ; j < 10 ; j++) {

if(arr[j] < arr[index])

index = j;

}

/*

temp = arr[i];

arr[i] = arr[index];

arr[index] = temp;

*/

swap(arr,i,index);

}

System.out.print("经过选择排序后:");

for(int i = 0 ; i < 10 ; i++)

System.out.print( arr[i] +" ");

System.out.println("");

}

冒泡排序是一种比较基础的排序算法,其思想是相邻的元素两两比较,较大的元素放后面,较小的元素放前面,这样一次循环下来,最大元素就会归位,若数组中元素个数为n,则经过(n-1)次后,所有元素就依次从小到大排好序了。整个过程如同气泡冒起,因此被称作冒泡排序。

选择排序代码如下:

public void Bubble_sort(int[] arr) {

int temp;

for(int i = 0 ; i < 9 ; i++) {

for(int j = 0 ; j < 10 - i - 1 ;j++) {

if(arr[j] > arr[j+1]) {

/*

temp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

*/

swap(arr,j,j+1);

}

}

}

System.out.print("经过冒泡排序后:");

for(int i = 0 ; i < 10 ; i++)

System.out.print( arr[i] +" ");

System.out.println("");

}

插入排序也是一种常见的排序算法,插入排序的思想是:创建一个与待排序数组等大的数组,每次取出一个待排序数组中的元素,然后将其插入到新数组中合适的位置,使新数组中的元素保持从小到大的顺序。

插入排序代码如下:

public void Insert_sort(int[] arr) {

int length = arr.length;

int[] arr_sort = new int[length];

int count = 0;

for(int i = 0;i < length; i++) {

if(count == 0) {

arr_sort[0] = arr[0];

}else if(arr[i] >= arr_sort[count - 1]) {

arr_sort[count] = arr[i];

}else if(arr[i] < arr_sort[0]) {

insert(arr,arr_sort,arr[i],0,count);

}else {

for(int j = 0;j < count - 1; j++) {

if(arr[i] >= arr_sort[j] && arr[i] < arr_sort[j+1]) {

insert(arr,arr_sort,arr[i],j+1,count);

break;

}

}

}

count++;

}

System.out.print("经过插入排序后:");

for(int i = 0 ; i < 10 ; i++)

System.out.print( arr_sort[i] +" ");

System.out.println("");

}

public void insert(int[] arr,int[] arr_sort,int value,int index,int count) {

for(int i = count; i > index; i--)

arr_sort[i] = arr_sort[i-1];

arr_sort[index] = value;

}

快速排序的效率比冒泡排序算法有大幅提升。因为使用冒泡排序时,一次外循环只能归位一个值,有n个元素最多就要执行(n-1)次外循环。而使用快速排序时,一次可以将所有元素按大小分成两堆,也就是平均情况下需要logn轮就可以完成排序。

快速排序的思想是:每趟排序时选出一个基准值(这里以首元素为基准值),然后将所有元素与该基准值比较,并按大小分成左右两堆,然后递归执行该过程,直到所有元素都完成排序。

public void Quick_sort(int[] arr, int left, int right) {

if(left >= right)

return ;


int temp,t;

int j = right;

int i = left;

temp = arr[left];

while(i < j) {

while(arr[j] >= temp && i < j)

j--;

while(arr[i] <= temp && i < j)

i++;

if(i < j) {

t = arr[i];

arr[i] = arr[j];

arr[j] = t;

}

}

arr[left] = arr[i];

arr[i] = temp;


Quick_sort(arr,left, i - 1);

Quick_sort(arr, i + 1, right);

}

归并排序是建立在归并操作上的一种有效的排序算法,归并排序对序列的元素进行逐层折半分组,然后从最小分组开始比较排序,每两个小分组合并成一个大的分组,逐层进行,最终所有的元素都是有序的。

public void Mergesort(int[] arr,int left,int right) {

if(right - left > 0) {

int[] arr_1 = new int[(right - left)/2 + 1];

int[] arr_2 = new int[(right - left + 1)/2];

int j = 0;

int k = 0;

for(int i = left;i <= right;i++) {

if(i <= (right + left)/2) {

arr_1[j++] = arr[i];

}else {

arr_2[k++] = arr[i];

}

}

Mergesort(arr_1,0,(right - left)/2);

Mergesort(arr_2,0,(right - left - 1)/2);

Merge(arr_1,arr_2,arr);

}

}

public void Merge(int[] arr_1,int[] arr_2,int[] arr) {

int i = 0;

int j = 0;

int k = 0;

int L1 = arr_1.length;

int L2 = arr_2.length;

while(i < L1 && j < L2) {

if(arr_1[i] <= arr_2[j]) {

arr[k] = arr_1[i];

i++;

}else {

arr[k] = arr_2[j];

j++;

}

k++;

}

if(i == L1) {

for(int t = j;j < L2;j++)

arr[k++] = arr_2[j];

}else {

for(int t = i;i < L1;i++)

arr[k++] = arr_1[i];

}

}

归并排序这里我使用了left,right等变量,使其可以通用,并没有直接用数字表示那么明确,所以给出相关伪代码,便于理解。

Mergesort(arr[0...n-1])

//输入:一个可排序数组arr[0...n-1]

//输出:非降序排列的数组arr[0...n-1]

if n>1

arr[0...n/2-1] to arr_1[0...(n+1)/2-1]//确保arr_1中元素个数>=arr_2中元素个数

//对于总个数为奇数时,arr_1比arr_2中元素多一个;对于总个数为偶数时,没有影响

arr[n/2...n-1] to arr_2[0...n/2-1]

Mergesort(arr_1[0...(n+1)/2-1])

Mergesort(arr_2[0...n/2-1])

Merge(arr_1,arr_2,arr)

Merge(arr_1[0...p-1],arr_2[0...q-1],arr[0...p+q-1])

//输入:两个有序数组arr_1[0...p-1]和arr_2[0...q-1]

//输出:将arr_1与arr_2两数组合并到arr

int i<-0;j<-0;k<-0

while i

<p span="" do<="" j

if arr_1[i] <= arr_2[j]

arr[k] <- arr_1[i]

i<-i+1

else arr[k] <- arr_2[j];j<-j+1

k<-k+1

if i=p

arr_2[j...q-1] to arr[k...p+q-1]

else arr_1[i...p-1] to arr[k...p+q-1]

package test_1;

import java.util.Scanner;

public class Test01 {

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int[] arr_1 = new int[10];

for(int i = 0 ; i < 10 ; i++)

arr_1[i] = sc.nextInt();

Sort demo_1 = new Sort();


//1~5一次只能运行一个,若多个同时运行,则只有第一个有效,后面几个是无效排序。因为第一个运行的已经将带排序数组排好序。


demo_1.Select_sort(arr_1);//-----------------------1


//demo_1.Bubble_sort(arr_1);//---------------------2


/* //---------------------3

demo_1.Quick_sort(arr_1, 0 , arr_1.length - 1);

System.out.print("经过快速排序后:");

for(int i = 0 ; i < 10 ; i++)

System.out.print( arr_1[i] +" ");

System.out.println("");

*/


//demo_1.Insert_sort(arr_1);//--------------------4


/* //--------------------5

demo_1.Mergesort(arr_1,0,arr_1.length - 1);

System.out.print("经过归并排序后:");

for(int i = 0 ; i < 10 ; i++)

System.out.print( arr_1[i] +" ");

System.out.println("");

*/

}

}

class Sort {

public void swap(int arr[],int a, int b) {

int t;

t = arr[a];

arr[a] = arr[b];

arr[b] = t;

}


public void Select_sort(int[] arr) {

int temp,index;

for( int i=0;i<10;i++) {

index = i;

for(int j = i + 1 ; j < 10 ; j++) {

if(arr[j] < arr[index])

index = j;

}

/*

temp = arr[i];

arr[i] = arr[index];

arr[index] = temp;

*/

swap(arr,i,index);

}

System.out.print("经过选择排序后:");

for(int i = 0 ; i < 10 ; i++)

System.out.print( arr[i] +" ");

System.out.println("");

}


public void Bubble_sort(int[] arr) {

int temp;

for(int i = 0 ; i < 9 ; i++) {

for(int j = 0 ; j < 10 - i - 1 ;j++) {

if(arr[j] > arr[j+1]) {

/*

temp = arr[j];

arr[j] = arr[j+1];

arr[j+1] = temp;

*/

swap(arr,j,j+1);

}

}

}

System.out.print("经过冒泡排序后:");

for(int i = 0 ; i < 10 ; i++)

System.out.print( arr[i] +" ");

System.out.println("");

}


public void Quick_sort(int[] arr, int left, int right) {

if(left >= right)

return ;


int temp,t;

int j = right;

int i = left;

temp = arr[left];

while(i < j) {

while(arr[j] >= temp && i < j)

j--;

while(arr[i] <= temp && i < j)

i++;

if(i < j) {

t = arr[i];

arr[i] = arr[j];

arr[j] = t;

}

}

arr[left] = arr[i];

arr[i] = temp;


Quick_sort(arr,left, i - 1);

Quick_sort(arr, i + 1, right);

}


public void Insert_sort(int[] arr) {

int length = arr.length;

int[] arr_sort = new int[length];

int count = 0;

for(int i = 0;i < length; i++) {

if(count == 0) {

arr_sort[0] = arr[0];

}else if(arr[i] >= arr_sort[count - 1]) {

arr_sort[count] = arr[i];

}else if(arr[i] < arr_sort[0]) {

insert(arr,arr_sort,arr[i],0,count);

}else {

for(int j = 0;j < count - 1; j++) {

if(arr[i] >= arr_sort[j] && arr[i] < arr_sort[j+1]) {

insert(arr,arr_sort,arr[i],j+1,count);

break;

}

}

}

count++;

}

System.out.print("经过插入排序后:");

for(int i = 0 ; i < 10 ; i++)

System.out.print( arr_sort[i] +" ");

System.out.println("");

}

public void insert(int[] arr,int[] arr_sort,int value,int index,int count) {

for(int i = count; i > index; i--)

arr_sort[i] = arr_sort[i-1];

arr_sort[index] = value;

}


public void Mergesort(int[] arr,int left,int right) {

if(right - left > 0) {

int[] arr_1 = new int[(right - left)/2 + 1];

int[] arr_2 = new int[(right - left + 1)/2];

int j = 0;

int k = 0;

for(int i = left;i <= right;i++) {

if(i <= (right + left)/2) {

arr_1[j++] = arr[i];

}else {

arr_2[k++] = arr[i];

}

}

Mergesort(arr_1,0,(right - left)/2);

Mergesort(arr_2,0,(right - left - 1)/2);

Merge(arr_1,arr_2,arr);

}

}

public void Merge(int[] arr_1,int[] arr_2,int[] arr) {

int i = 0;

int j = 0;

int k = 0;

int L1 = arr_1.length;

int L2 = arr_2.length;

while(i < L1 && j < L2) {

if(arr_1[i] <= arr_2[j]) {

arr[k] = arr_1[i];

i++;

}else {

arr[k] = arr_2[j];

j++;

}

k++;

}

if(i == L1) {

for(int t = j;j < L2;j++)

arr[k++] = arr_2[j];

}else {

for(int t = i;i < L1;i++)

arr[k++] = arr_1[i];

}

}

}

若有错误,麻烦指正,不胜感激。

阅读全文

与swap算法教学视频相关的资料

热点内容
产品经理和程序员待遇 浏览:439
解忧程序员免费阅读 浏览:106
录像免压缩 浏览:504
总结所学过的简便算法 浏览:360
南昌哪些地方需要程序员 浏览:759
三台服务器配置IP地址 浏览:173
如何用命令方块连续对话 浏览:278
win7linux共享文件夹 浏览:304
命令符打开本地服务 浏览:599
android应用程序源码 浏览:703
安卓开发工程师简历怎么写 浏览:61
热水器水量服务器是什么意思 浏览:117
stk卫星编译 浏览:480
对后台程序员的要求 浏览:761
ios大文件夹图标 浏览:626
生的计划pdf 浏览:715
oppoa93加密便签在哪查找 浏览:21
两个数字的加减乘除运算编程 浏览:227
给手机加密码忘记了怎么办 浏览:601
单片机运算符 浏览:297