排序算法总结--C++代码实现

1.常见排序算法

 

 

 

 

 

2. 插入排序

2.1 直接插入排序


void print(int *arr, int nCount, int n=0)
{
	int i = 0;
	printf("%d==== ", n);
	while(i < nCount) printf("%2d  ", arr[i++]);
	printf("\n");
}
// Straight Insertion Sort
void InsertSort(int* arr, int nCount)
{
	if (arr == NULL || nCount < 2)
	{
		return;
	}

	for(int i = 1; i < nCount; i++)
	{
		if(arr[i] < arr[i-1])
		{	
			int t= arr[i];
			int j = i;
			while((j > 0) && (t <= arr[j-1]))
			{
				arr[j] = arr[j-1];
				j--;
			}
			arr[j] = t;
		}
	}
}

2.2 希尔排序 -- 插入

void print(int *arr, int nCount, int n=0)
{
	int i = 0;
	printf("%d==== ", n);
	while(i < nCount) printf("%2d  ", arr[i++]);
	printf("\n");
}
// ShellInsertSort
void ShellInsertSort(int* arr, int nCount)
{
	if (arr == NULL || nCount < 2)
	{
		return;
	}
	int dk = nCount/2;
	while(dk > 0)
	{
		for(int i = dk; i < nCount; i++)
		{
			if (arr[i] < arr[i-dk])
			{
				int t = arr[i];
				int j = i;
				while(j-dk>=0 && arr[j-dk]>t)
				{
					arr[j] = arr[j-dk];
					j-=dk;
				}
				arr[j] = t;
			}
			print(arr,nCount,i);
		}
		print(arr,nCount,dk);
		dk = dk/2;
	}
}

3. 选择排序

3.1直接选择排序

#include<iostream>

void print(int a[], int n ,int i){  
    std::cout<<"第"<<i+1 <<"趟 : ";  
    for(int j= 0; j<8; j++){  
        std::cout<<a[j] <<"  ";  
    }  
    std::cout<<std::endl;  
}  
/** 
 * 数组的最小值 
 * 
 * @return int 数组的键值 
 */  
int SelectMinKey(int a[], int n, int i)  
{  
    int k = i;  
    for(int j=i+1 ;j< n; ++j) {  
        if(a[k] > a[j]) k = j;  
    }  
    return k;  
}  
  
/** 
 * 选择排序 
 * 
 */  
void selectSort(int a[], int n){  
    int key, tmp;  
    for(int i = 0; i< n; ++i) {  
        key = SelectMinKey(a, n,i);           //选择最小的元素  
        if(key != i){  
            tmp = a[i];  a[i] = a[key]; a[key] = tmp; //最小元素与第i位置元素互换  
        }  
        print(a,  n , i);  
    }  
}  

/**
* 优化
*/
void SelectSort(int r[],int n) {  
    int i ,j , min ,max, tmp;  
    for (i=1 ;i <= n/2;i++) {    
        // 做不超过n/2趟选择排序   
        min = i; max = i ; //分别记录最大和最小关键字记录位置  
        for (j= i+1; j<= n-i; j++) {  
            if (r[j] > r[max]) {   
                max = j ; continue ;   
            }    
            if (r[j]< r[min]) {   
                min = j ;   
             }     
      }    
      //该交换操作还可分情况讨论以提高效率  
      tmp = r[i-1]; r[i-1] = r[min]; r[min] = tmp;  
      tmp = r[n-i]; r[n-i] = r[max]; r[max] = tmp;   
  
    }   
} 
int main(){  
    int a[8] = {3,1,5,7,2,4,9,6};  
    std::cout<<"初始值:";  
    for(int j= 0; j<8; j++){  
        std::cout<<a[j] <<"  ";  
    }  
    std::cout<<std::endl<<std::endl;  
    selectSort(a, 8);  
    print(a,8,8);  
}  

3.2堆排序--选择 

#include<iostream>
using namespace std;

void print(int a[], int n){  
    for(int j= 0; j<n; j++){  
        cout<<a[j] <<"  ";  
    }  
    cout<<endl;  
}  

/** 
 * 已知H[s…m]除了H[s] 外均满足堆的定义 
 * 调整H[s],使其成为大顶堆.即将对第s个结点为根的子树筛选,  
 * 
 * @param H是待调整的堆数组 
 * @param s是待调整的数组元素的位置 
 * @param length是数组的长度 
 * 
 */  
void HeapAdjust(int H[],int s, int length)  
{  
    int tmp  = H[s];  
    int child = 2*s+1; //左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置)  
    while (child < length) {  
        if(child+1 <length && H[child]<H[child+1]) { // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点)  
            ++child ;  
        }  
        if(H[s]<H[child]) {  // 如果较大的子结点大于父结点  
            H[s] = H[child]; // 那么把较大的子结点往上移动,替换它的父结点  
            s = child;       // 重新设置s ,即待调整的下一个结点的位置  
            child = 2*s+1;  
        }  else {            // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出  
             break;  
        }  
        H[s] = tmp;         // 当前待调整的结点放到比其大的孩子结点位置上  
    }  
    print(H,length);  
}  
  
/** 
 * 初始堆进行调整 
 * 将H[0..length-1]建成堆 
 * 调整完之后第一个元素是序列的最小的元素 
 */  
void BuildingHeap(int H[], int length)  
{   
    //最后一个有孩子的节点的位置 i=  (length -1) / 2  
    for (int i = (length -1) / 2 ; i >= 0; --i)  
        HeapAdjust(H,i,length);  
} 
 
/** 
 * 堆排序算法 
 */  
void HeapSort(int H[],int length)  
{  
    //初始堆  
    BuildingHeap(H, length);  
    //从最后一个元素开始对序列进行调整  
    for (int i = length - 1; i > 0; --i)  
    {  
        //交换堆顶元素H[0]和堆中最后一个元素  
        int temp = H[i]; H[i] = H[0]; H[0] = temp;  
        //每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整  
        HeapAdjust(H,0,i);  
  }  
}   
  
int main(){  
    int H[10] = {3,1,5,7,2,4,9,6,10,8};  
    cout<<"初始值:";  
    print(H,10);  
    HeapSort(H,10);  
    //selectSort(a, 8);  
    cout<<"结果:";  
    print(H,10);  
  
}  

4. 交换排序

4.1 冒泡排序

void print(int *arr, int nCount, int n=0)
{
	int i = 0;
	printf("%d==== ", n);
	while(i < nCount) printf("%2d  ", arr[i++]);
	printf("\n");
}

 void BubbleSort(int *arr, int nCount)
 {
	for(int i = 0; i < nCount; i++)
	{
		for(int j = 1; j < nCount-i; j++)
		{
			if (arr[j-1] > arr[j])
			{
				arr[j-1] += arr[j];
				arr[j] = arr[j-1] - arr[j];
				arr[j-1] = arr[j-1] - arr[j];
			}
		}
		print(arr, 10, i);
	}
 }
 

4.2 快速排序

#include<iostream>
using namespace std;

void print(int a[], int n){  
    for(int j= 0; j<n; j++){  
        cout<<a[j] <<"  ";  
    }  
    cout<<endl;  
}  
  
void swap(int *a, int *b)  
{  
    int tmp = *a;  
    *a = *b;  
    *b = tmp;  
}  
  
int partition(int a[], int low, int high)  
{  
    int privotKey = a[low];                             //基准元素  
    while(low < high){                                   //从表的两端交替地向中间扫描  
        while(low < high  && a[high] >= privotKey) --high;  //从high 所指位置向前搜索,至多到low+1 位置。将比基准元素小的交换到低端  
        swap(&a[low], &a[high]);  
        while(low < high  && a[low] <= privotKey ) ++low;  
        swap(&a[low], &a[high]);  
    }  
    print(a,10);  
    return low;  
}  
  
void quickSort(int a[], int low, int high){  
    if(low < high){  
        int privotLoc = partition(a,  low,  high);  //将表一分为二  
        quickSort(a,  low,  privotLoc -1);          //递归对低子表递归排序  
        quickSort(a,   privotLoc + 1, high);        //递归对高子表递归排序  
    }  
}  
  
int main(){  
    int a[10] = {3,1,5,7,2,4,9,6,10,8};  
    cout<<"初始值:";  
    print(a,10);  
    quickSort(a,0,9);  
    cout<<"结果:";  
    print(a,10);  
  
}  

优化快速排序

#include<iostream>
using namespace std;

void print(int a[], int n){  
    for(int j= 0; j<n; j++){  
        cout<<a[j] <<"  ";  
    }  
    cout<<endl;  
}  
  
void swap(int *a, int *b)  
{  
    int tmp = *a;  
    *a = *b;  
    *b = tmp;  
}  
  
int partition(int a[], int low, int high)  
{  
    int privotKey = a[low];                 //基准元素  
    while(low < high){                   //从表的两端交替地向中间扫描  
        while(low < high  && a[high] >= privotKey) --high; //从high 所指位置向前搜索,至多到low+1 位置。将比基准元素小的交换到低端  
        swap(&a[low], &a[high]);  
        while(low < high  && a[low] <= privotKey ) ++low;  
        swap(&a[low], &a[high]);  
    }  
    print(a,10);  
    return low;  
}   
  
void qsort_improve(int r[ ],int low,int high, int k){  
    if( high -low > k ) { //长度大于k时递归, k为指定的数  
        int pivot = partition(r, low, high); // 调用的Partition算法保持不变  
        qsort_improve(r, low, pivot - 1,k);  
        qsort_improve(r, pivot + 1, high,k);  
    }   
}   
void quickSort(int r[], int n, int k){  
    qsort_improve(r,0,n,k);//先调用改进算法Qsort使之基本有序  
  
    //再用插入排序对基本有序序列排序  
    for(int i=1; i<=n;i ++){  
        int tmp = r[i];   
        int j=i-1;  
        while(tmp < r[j]){  
            r[j+1]=r[j]; j=j-1;   
        }  
        r[j+1] = tmp;  
    }   
  
}  
  
int main(){  
    int a[10] = {3,1,5,7,2,4,9,6,10,8};  
    cout<<"初始值:";  
    print(a,10);  
    quickSort(a,9,4);  
    cout<<"结果:";  
    print(a,10);  
  
}  

5. 归并排序

归并的合并方法:

//将r[i…m]和r[m +1 …n]归并到辅助数组rf[i…n]  
void Merge(ElemType *r,ElemType *rf, int i, int m, int n)  
{  
    int j,k;  
    for(j=m+1,k=i; i<=m && j <=n ; ++k){  
        if(r[j] < r[i]) rf[k] = r[j++];  
        else rf[k] = r[i++];  
    }  
    while(i <= m)  rf[k++] = r[i++];  
    while(j <= n)  rf[k++] = r[j++];  
} 

归并的迭代算法

#include<iostream>
using namespace std;

void print(int a[], int n){  
    for(int j= 0; j<n; j++){  
        cout<<a[j] <<"  ";  
    }  
    cout<<endl;  
}  
  
//将r[i…m]和r[m +1 …n]归并到辅助数组rf[i…n]  
void Merge(ElemType *r,ElemType *rf, int i, int m, int n)  
{  
    int j,k;  
    for(j=m+1,k=i; i<=m && j <=n ; ++k){  
        if(r[j] < r[i]) rf[k] = r[j++];  
        else rf[k] = r[i++];  
    }  
    while(i <= m)  rf[k++] = r[i++];  
    while(j <= n)  rf[k++] = r[j++];  
    print(rf,n+1);  
}  
  
void MergeSort(ElemType *r, ElemType *rf, int lenght)  
{   
    int len = 1;  
    ElemType *q = r ;  
    ElemType *tmp ;  
    while(len < lenght) {  
        int s = len;  
        len = 2 * s ;  
        int i = 0;  
        while(i+ len <lenght){  
            Merge(q, rf,  i, i+ s-1, i+ len-1 ); //对等长的两个子表合并  
            i = i+ len;  
        }  
        if(i + s < lenght){  
            Merge(q, rf,  i, i+ s -1, lenght -1); //对不等长的两个子表合并  
        }  
        tmp = q; q = rf; rf = tmp; //交换q,rf,以保证下一趟归并时,仍从q 归并到rf  
    }  
}  

int main(){  
    int a[10] = {3,1,5,7,2,4,9,6,10,8};  
    int b[10];  
    MergeSort(a, b, 10);  
    print(b,10);  
    cout<<"结果:";  
    print(a,10);  
  
}  

 

两路归并的递归算法

void MSort(ElemType *r, ElemType *rf,int s, int t)  
{   
    ElemType *rf2;  
    if(s==t) r[s] = rf[s];  
    else  
    {   
        int m=(s+t)/2;          /*平分*p 表*/  
        MSort(r, rf2, s, m);        /*递归地将p[s…m]归并为有序的p2[s…m]*/  
        MSort(r, rf2, m+1, t);      /*递归地将p[m+1…t]归并为有序的p2[m+1…t]*/  
        Merge(rf2, rf, s, m+1,t);   /*将p2[s…m]和p2[m+1…t]归并到p1[s…t]*/  
    }  
}  
void MergeSort_recursive(ElemType *r, ElemType *rf, int n)  
{   /*对顺序表*p 作归并排序*/  
    MSort(r, rf,0, n-1);  
}

6. 基数排序

Void RadixSort(Node L[],length,maxradix)  
{  
   int m,n,k,lsp;  
   k=1;m=1;  
   int temp[10][length-1];  
   Empty(temp); //清空临时空间  
   while(k<maxradix) //遍历所有关键字  
   {  
     for(int i=0;i<length;i++) //分配过程  
    {  
       if(L[i]<m)  
          Temp[0][n]=L[i];  
       else  
          Lsp=(L[i]/m)%10; //确定关键字  
       Temp[lsp][n]=L[i];  
       n++;  
   }  
   CollectElement(L,Temp); //收集  
   n=0;  
   m=m*10;  
  k++;  
 }  
}  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值