C++ 八种排序算法总结及实现_c排序算法总结

2020-02-27 其他工作总结 下载本文

C++ 八种排序算法总结及实现由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“c排序算法总结”。

八种排序算法总结之C++版本

五种简单排序算法

一、冒泡排序

【稳定的】

void BubbleSort(int* a,int Count)//实现从小到大的最终结果 { int temp;for(int i=1;i

for(int j=Count-1;j>=i;j--)

if(a[j]

{

temp = a[j];

a[j] = a[j-1];

a[j-1] = temp;

} }

现在注意,我们给出O方法的定义:

若存在一常量K和起点n0,使当n>=n0时,有f(n)

现在我们来看1/2*(n-1)*n,当K=1/2,n0=1,g(n)=n*n时,1/2*(n-1)*n

二、交换排序

【稳定的】

void ExchangeSort(int *a,int Count){ int temp;for(int i=0;i

for(int j=i+1;j

if(a[j]

{

temp = a[j];

a[j] = a[i];

a[i] = temp;

} }

时间复杂度为O(n*n)。

三、选择法

【不稳定的】

void SelectSort(int *a,int Count){ int temp;//一个存储值

int pos;//一个存储下标

for(int i=0;i

temp = a[i];

pos = i;

for(int j=i+1;j

if(a[j]

{

temp = a[j];

pos = j;//下标的交换赋值,记录当前最小元素的下标位置

}

a[pos] = a[i];

a[i] = temp;} }

遗憾的是算法需要的循环次数依然是1/2*(n-1)*n。所以算法复杂度为O(n*n)。

我们来看他的交换。由于每次外层循环只产生一次交换(只有一个最小值)。所以f(n)

四、插入法

【稳定的】

void InsertSort(int *a,int Count){ int temp;//一个存储值

int pos;//一个存储下标

for(int i=1;i

{

temp = a[i];//当前要插入的元素

pos = i-1;

while(pos>=0 && temp

{

a[pos+1] = a[pos];//将前一个元素后移一位

pos--;

}

a[pos+1] = temp;} }

其复杂度仍为O(n*n)。

最终,我个人认为,在简单排序算法中,直接插入排序是最好的。

五、希尔排序法

【不稳定的】 /* * 希尔排序,n为数组的个数 */ void ShellSort(int arr[], int n){ int temp,pos;int d = n;//增量初值

do{

d = d/3 + 1;

for(int i= d;i

{

temp = arr[i];

pos = i-d;

while(pos>=0 && temp

arr[ pos + d ] = arr[pos];

pos-= d;

}

arr[ pos + d ] = temp;

} } while(d > 1);}

//实现增量为d的插入排序

三种高级排序算法

一、快速排序

辅助空间复杂度为O(1)

【不稳定的】 void QuickSort(int *a,int left, int right){ int i,j,middle,temp;i = left;j = right;middle = a[(left+right)/2 ];do {

while(a[i]

i++;

while(a[j]>middle && j>left)//从右扫描小于中值的数

j--;

if(i

{

temp = a[i];

a[i] = a[j];

}

a[j] = temp;

i++;

j--;}

} while(ii),递归右半边 if(i

注意,在扫描过程中,对于给定参考值,对于向右(左)扫描,如果扫描值大(小)于或等于参考值,就需要进行交换。最终得到的结果是,j左边的值都小于参考值,而i右边的值都大于参考值,j和i之间的值都等于参考值。对j左边和i右边的分别使用递归,就可以完成最终的排序。

这里我没有给出行为的分析,因为这个很简单,我们直接来分析算法:首先我们考虑最理想的情况

1.数组的大小是2的幂,这样分下去始终可以被2整除。假设为2的k次方,即k=log2(n)。

2.每次我们选择的值刚好是中间值,这样,数组才可以被等分。

第一层递归,循环n次,第二层循环2*(n/2)......所以共有n+2(n/2)+4(n/4)+...+n*(n/n)= n+n+n+...+n=k*n=log2(n)*n 所以算法复杂度为O(log2(n)*n)

其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变

成交换法(由于使用了递归,情况更糟),但是糟糕的情况只会持续一个流程,到下一个流程的时候就很可能已经避开了该中间的最大和最小值,因为数组下标变化了,于是中间值不在是那个最大或者最小值。但是你认为这种情况发生的几率有多大??呵呵,你完全不必担心这个问题。实践证明,大多数的情况,快速排序总是最好的。

如果你担心这个问题,你可以使用堆排序,这是一种稳定的O(log2(n)*n)算法,但是通常情况下速度要慢

于快速排序(因为要重组堆)。

二、归并排序(两种实现方法均要掌握)

【稳定的】

归并排序是一种极好的外部排序方法,即针对数据保存在磁盘上而不是高速内存中的问题。

//以下程序参考数据结构课本P286页的模板,为使用指针链表实现的 #include using namespace std;

struct node{ //链表的节点数据

int value;node *next;};

node * divide_from(node * head){ node * position, * midpoint, * second_half;if((midpoint=head)== NULL)//List is empty

return NULL;position = midpoint->next;while(position!= NULL)//Move position twice for midpoint's one move {

position = position->next;

if(position!= NULL)

{

midpoint = midpoint->next;

position = position->next;

}

} second_half = midpoint->next;midpoint->next = NULL;//在这里将原链拆断,分为两段

return second_half;}

node * merge(node * first, node * second){ node * last_sorted;//当前已经链接好的有序链中的最后一个节点

node combined;//哑节点

last_sorted = &combined;while(first!=NULL && second!=NULL){

if(first->value value){

last_sorted->next = first;

last_sorted = first;

first = first->next;

}else {

last_sorted->next = second;

last_sorted = second;

second = second->next;

} } if(first==NULL)

last_sorted->next = second;else

last_sorted->next = first;return combined.next;//返回哑节点的后继指针,即为合并后的链表的头指针 }

//这里的参数必须是引用调用,需要这个指引去允许函数修改调用自变量 void MergeSort(node * &head){ if(head!= NULL && head->next!= NULL)//如果只有一个元素,则不需排序 {

node * second_half = divide_from(head);

MergeSort(head);

MergeSort(second_half);

head = merge(head, second_half);} }

int main(){ node a,b,c,d;node *p1, *p2, *p3, *p4,*head;p1 = &a;p2 = &b;p3 = &c;p4 = &d;a.value = 2;b.value = 4;c.value = 3;d.value = 1;a.next = p2;b.next = p3;c.next = p4;d.next = NULL;//调用归并排序前的结果

head = p1;while(head!= NULL){

coutvalue

head = head->next;} cout

head = p1;while(head!= NULL){

coutvalue

head = head->next;} cout

//以下程序为使用数组实现的归并排序,辅助空间复杂度为O(n)

#include using namespace std;

void Merge(int data[], int left, int mid, int right){ int n1,n2,k,i,j;n1 = midmid;int *L = new int[n1];//两个指针指向两个动态数组的首地址

int *R = new int[n2];for(i=0,k=left;i

L[i] = data[k];for(i=0,k=mid+1;i

R[i] = data[k];for(k=left,i=0,j=0;i

if(L[i]

data[k] = L[i];

i++;

} else {

data[k] = R[j];

j++;

} } if(i

for(j=i;j

} /* * left:数组的开始下标,一般为0;right:数组的结束下标,一般为(n-1)*/

void MergeSort(int data[], int left, int right){ if(left

int mid = left +(right-left)/ 2;//mid=(right+left)/2,防止溢出

MergeSort(data, left, mid);

MergeSort(data , mid+1, right);

Merge(data , left, mid , right);} }

int main(){ int data[] = {9,8,7,2,5,6,3,55,1};//排序前的输出

for(int i=0;i

cout

for(int i=0;i

cout

三、堆排序 【不稳定的】

/* * 向堆中插入current元素的函数 */ void insert_heap(int data[], const int ¤t, int low, int high)

data[k] = L[j];else //if(j

for(i=j;i

data[k] = R[i];delete []L;//回收内存 delete []R;{ int large;//元素data[low]左右儿子中,大者的位置

large = 2*low + 1;while(large

if(large

large++;

if(current > data[ large ])//待插入元素的值比它的两个儿子都大

break;

else {

data[ low ] = data[ large ];//将其左右儿子的大者上移

low = large;

large = 2 * large + 1;

} } data[ low ] = current;} /* * 建立堆函数,num为数组data的元素个数

* 只有一个结点的自动满足堆的属性,因此不必担心树中的任何树叶,即 * 不必担心表的后一半中的元素。如果从表的中间点开始并从后向前工作,就 * 能够使用函数insert_heap去将每个元素插入到包含了所有后面元素的部分堆 * 中,从而创建完整的堆。*/ void build_heap(int data[], int num){

int current;for(int low = num/2-1;low>=0;low--){

current = data[ low ];

insert_heap(data, current, low, num-1);} } /* * 堆排序主函数,num为数组data的元素个数 */ void heap_sort(int data[], int num){ int current, last_sorted;build_heap(data, num);//建立堆

for(last_sorted = num-1;last_sorted>0;last_sorted--){ //逐个元素处理

current = data[ last_sorted ];//data[0]在整个数组排序结束前,存储的是待排序元素中最大的元素

data[last_sorted] = data[0];

insert_heap(data, current, 0, last_sorted-1);} } int main(){ //用于排序算法的输入输出

int a[8] = {5,7,1,2,9,4,6,3,};for(int i=0;i

cout

for(int i=0;i

cout

《C++ 八种排序算法总结及实现.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
C++ 八种排序算法总结及实现
点击下载文档
相关专题 c排序算法总结 算法 八种 c排序算法总结 算法 八种
[其他工作总结]相关推荐
    [其他工作总结]热门文章
      下载全文