首页 > 数据结构 > 排序 阅读:57,774

交换排序

交换排序的基本思想是:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。

6.3.1冒泡排序

首先来看著名的交换排序算法:冒泡法。冒泡法的排序思想是:从第n个元素(a[n-1])开始,扫描数组,比较相邻两个元素,如果次序相反则交换。如此反复,直到没有任何两个违反相反原则的元素

 

假如待排数据为:9,6,2,3,10,那么每趟冒泡排序之后(从小到大),数据的变化情况为:

2,9,6,3,10

2,3,9,6,10

2,3,6,9,10

2,3,6,9,10

 

冒泡排序的算法如下:

 
    void bubble_sort(int a[], int n){

       int i, j, tmp;

       for (i = 0; i < n-1; i++) {
              for (j = n-1; j >= i+1; j--){

                     if (a[j] < a[j-1]){

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

冒泡排序的时间复杂度为O(n^2),它是稳定排序。

 

6.3.2快速排序

快速排序的思想是:在当前无序区R[1..H]中任取一个数据元素作为比较的“基准”(不妨记为XR[1]),用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]XR[I+ 1..H](1IH),当R[1..I-1]R[I+1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。

 

找一个数X(比如头一个元素)做基准,右边比X小的移动到左边,左边比X大的移动到右边,最后空出的位置就是X自己的位置

 

快速排序的时间复杂度为O(nlogn),最坏情况为O(n^2)。对于大的、乱数序列一般相信是最快的已知排序。待排记录序列按关键字顺序有序时,直接插入排序和起泡排序能达到O(n)的时间复杂度,而对于快速排序而言,这是最不好的情况。对于很小的数组(如N<=20),快速排序不如插入排序好。

 
void quickSort(int a[],int left,int right){

   int i,j,temp;

   i=left;

   j=right;

   temp=a[left];

   if(left>right)

      return;

   while(i<j){

      while(a[j]>=temp && j>i)

         j--;

      if(j>i)

         a[i++]=a[j];

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

          i++;

      if(j>i)

          a[j--]=a[i];

   }

   a[i]=temp;

   quickSort(a,left,i-1);/*递归左边*/

   quickSort(a,i+1,right);/*递归右边*/

}

void qsort(int a[], int n){

       quickSort(a, 0, n-1);

}
快速排序非递归版:

typedef struct _data {
	int low;
	int high;
}DATA;
#define MAX 100


void quick_sort(int a[], int low, int high) {
	DATA stack[MAX]={0};
	int top = 0;
	stack[0].low = low;
	stack[0].high = high;

	while(top>=0){

		int l = stack[top].low;
		int i = stack[top].low;
		int j = stack[top].high;
		int h = stack[top].high;

		top--;

		if(i>=j) {
			continue;
		}

		int tmp = a[i];
		while(i<j) {
			while(a[j]>=tmp&&i<j) {
				j--;
			}
			if(i<j) {
				a[i] = a[j];
				i++;
			}
			while(a[i]<=tmp&&i<j) {
				i++;
			}
			if(i<j) {
				a[j]=a[i];
				j--;
			}
		}
		a[i]=tmp;

		DATA data;
		data.low = l;
		data.high = i-1;
		if(top<MAX){
			top++;
			stack[top] = data;
			
		}
		data.low = i+1;
		data.high = h;
		if(top<MAX) {
			top++;
			stack[top] = data;
			
		}	
	}
}

周哥教IT,分享编程知识,提高编程技能,程序员的充电站。跟着周哥一起学习,每天都有进步。

通俗易懂,深入浅出,一篇文章只讲一个知识点。

当你决定关注「周哥教IT」,你已然超越了90%的程序员!

IT黄埔-周哥教IT技术交流QQ群:213774841,期待您的加入!

二维码
微信扫描二维码关注