排序算法小合集:冒泡排序、快速排序、堆排序、合并排序、插入排序
相关知识:
假设:含n个记录的序列为:{R1,R2,…,Rn}
相应的关键字序列为:{K1,K2,…,Kn}
需确定1,2,…,n的一种排列p1,p2,…,pn,使其相应的关键字满足如下的非递减(或非递增)关系: Kp1 <=Kp2<= … <=Kpn
使得记录的序列成为一个按关键字有序的序列:
{Rp1,Rp2,…,Rpn}
这样的一种操作称为排序。
假设Ki=Kj(1<=i<=n,1<=j<=n,i!=j),且在排序前序列中Ri领先于Rj(及i<j)。若在排序后的序列中Ri仍领先于 Rj,则称所用的排序方法是稳定的;反之,排序方法是不稳定的。
冒泡排序:Time(O(n2))
1 /************************************************************************/ 2 /* 函 数 名: BubbleSort() 3 /* 输入参数: int iArr[], int n //n为数组长度 4 /* 输出参数: 无 5 /* 返 回 值: int* 6 /* 功能描述: 输入一个数组,使用冒泡排序,将其排序(从小到大),返回数组指针 7 /* 日 期: 2012-10-2 8 /***********************************************************************/ 9 10 int* BubbleSort(int iArr[], int n) 11 { 12 for (int i=0; i<n; i++) 13 { 14 for (int j=i+1; j<n; j++) 15 { 16 if (iArr[i]>iArr[j]) 17 { 18 int temp = iArr[i]; 19 iArr[i] = iArr[j]; 20 iArr[j] = temp; 21 } 22 } 23 } 24 return iArr; 25 }
快速排序:(Time(O(nlogn)))
/************************************************************************/ /* 函 数 名: Partition() /* 输入参数: int iArr[], int low, int higt /* 输出参数: 无 /* 返 回 值: int /* 功能描述: 完成一次快排 /* 日 期: 2012-10-5 /***********************************************************************/ int Partition(int iArr[], int low, int high) { int pivotkey = iArr[low]; //存储枢轴值 while(low < high) //从表两端交替地向中间扫描 { //把比枢轴值小的值移到前面 while(low<high && iArr[high]>=pivotkey) { --high; } iArr[low] = iArr[high]; //把比枢轴值大的值移到前面 while(low<high && iArr[low]<=pivotkey) { ++low; } iArr[high] = iArr[low]; } iArr[low] = pivotkey; return low; //返回枢轴位置 } /************************************************************************/ /* 函 数 名: QSort() /* 输入参数: int iArr[], int low, int higt //low为第一个数的位置, high为最后一个数的位置(数组长度减1) /* 输出参数: 无 /* 返 回 值: int* /* 功能描述: 输入一个数组,使用快速排序,将其排序(从小到大),返回数组指针 /* 日 期: 2012-10-5 /***********************************************************************/ int* QSort(int iArr[], int low, int high) { if (low<high) { int pivotloc = Partition(iArr, low, high); //将数组一分为二 QSort(iArr, low, pivotloc-1); QSort(iArr, pivotloc+1, high); } return iArr; }
堆排序:(Time(O(nlogn)))
/************************************************************************/ /* 函 数 名: HeapAdjust() /* 输入参数: int iArr[], int s, int m // /* 输出参数: 无 /* 返 回 值: void /* 功能描述: 已知iArr[s...m]中记录的关键字除iArr[s]外均满足堆的定义, 本函数调整iArr[s...m]的关键字,使得其成为一个大顶堆 (对其中记录的关键字而言) /* 日 期: 2012-10-5 /***********************************************************************/ void HeapAdjust(int iArr[], int s, int m) {//已知iArr[s...m]中记录的关键字除iArr[s]外均满足堆的定义,本函数调整 //iArr[s...m]的关键字,使得其成为一个大顶堆(对其中记录的关键字而言) int rc = iArr[s]; //沿较大孩子结点向下筛选 for (int j=2*s; j<=m; j*=2) { //j为值较大的下标 if (j<m && iArr[j]<iArr[j+1]) { j++; } //rc应插入在s处 if (rc>=iArr[j]) { break; } iArr[s] = iArr[j]; s = j; } iArr[s] = rc; } /************************************************************************/ /* 函 数 名: HeapSort() /* 输入参数: int iArr[], int n //n为数组长度减1(参与排序元素的个数) /* 输出参数: 无 /* 返 回 值: int* /* 功能描述: 大顶堆排序,返回升序 !!注意:iArr中的iArr[0]不存值,或是说这个值不参与排序。 /* 日 期: 2012-10-5 /***********************************************************************/ int* HeapSort(int iArr[], int n) {//注意:iArr中的iArr[0]不存值,或是说这个值不参与排序。 for (int i=n/2; i>0; i--) { HeapAdjust(iArr, i, n); } for (int i = n; i>1; i--) { int temp = iArr[1]; iArr[1] = iArr[i]; iArr[i] = temp; HeapAdjust(iArr, 1, i-1); } return iArr; }
合并排序:
/************************************************************************/ /* 函 数 名: MergeSort() /* 输入参数: int iArr[], int begin, int end //end为数组下标最大值 /* 输出参数: 无 /* 返 回 值: int* /* 功能描述: 输入一个数组,使用合并排序,将其排序(从小到大),返回数组指针 /* 日 期: 2012-9-18 /***********************************************************************/ void Merge(int* iArr, int begin, int mid, int end); int * MergeSort(int iArr[], int begin, int end) { if (begin < end) { int mid = (begin + end)/2; MergeSort(iArr, begin, mid); MergeSort(iArr, mid+1, end); Merge(iArr, begin, mid, end); } return iArr; } void Merge(int* iArr, int begin, int mid, int end) { int n1 = mid - begin + 1; int n2 = end - mid; int* LArr = new int[n1+1]; int* RArr = new int[n2+1]; int i=0; int j=0; for (; i<n1; i++) { LArr[i] = iArr[begin+i]; } for (; j<n2; j++) { RArr[j] = iArr[mid+j+1]; } LArr[n1] = 1000; RArr[n2] = 1000; i = 0; j = 0; for (int k=begin; k<=end; k++) { if (LArr[i] <= RArr[j]) { iArr[k] = LArr[i++]; } else { iArr[k] = RArr[j++]; } } delete[] LArr; delete[] RArr; }
插入排序:
1 /************************************************************************/ 2 /*内容:本源代码主要为排序函数 3 /* 4 /************************************************************************/ 5 6 /************************************************************************/ 7 /* 函 数 名: InsertionSort() 8 /* 输入参数: int[], int 9 /* 输出参数: 无 10 /* 返 回 值: int* 11 /* 功能描述: 输入一个数组,使用插入排序,将其排序(从小到大),返回数组指针 12 /* 日 期: 2012-9-18 13 /***********************************************************************/ 14 15 int* InsertionSort(int iArr[], int n) 16 { 17 for (int j=1; j<n; j++) 18 { 19 int key = iArr[j]; 20 int i = j-1; 21 while(i>=0 && iArr[i]>key) 22 { 23 iArr[i+1] = iArr[i]; 24 i--; 25 } 26 iArr[i+1] = key; 27 } 28 29 return iArr; 30 }