八大排序 C++

 

01直接插入排序

void sort(int *a,int num)

{

    int i ,j ,key ;

    for (  i = 1; i < num; i++)

    {  

       int key = a[i];  //哨兵,数组取值都是挖空

       for ( j = i;j>0 && a[j-1] > key; j--)

       {//挖空的前一个位置和key关键字比较

           a[j] = a[j-1]; //往后移动元素

       }

       a[j] = key;

    }//如果关键字大于前面的那个就直接插入

}

02简单选择排序

void sort(int *a, int n)

{

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

         {

                   int key = a[i];

                   int index = i;

                   for (int j = i+1; j < n; j++)

                   {

                            if (a[j] < key)

                            {

                                     key = a[j];

                                     index = j;

                            }

                   }//寻找最小元素以及最小元素的下标

                   int tmp = a[i];//和之前的进行换序操作

                   a[index] = tmp;

                   a[i] = key;

         }

}

03冒泡排序

void sort(int *a, int n)

{

         for (int i = 0; i < n; i++) //外层循环控制排序次数

         {

                   for (int j = 0; j < n - 1 - i; j++) //内层循环每排序一次就少一个数

                  { //如果前面的比后面的大就后移动一个

                            if (a[j]>a[j + 1])

                            {

                                     int tmp = a[j + 1];

                                     a[j + 1] = a[j];

                                     a[j] = tmp;  //相邻两个进行比较,然后向后移动

                            }

                   }

         }

}

04快速排序

void quick_sort(int a[], int l, int r)

{

         if (l < r) //递归结束条件

         {

                   int i = l; int j = r;

                   int x = a[l];

                            while (i

                            {

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

                                               j--;//从后往前面找比x小的,找到以后将其挖出来,然后前移

                                     if (i < j)

                                               a[i++] = a[j];  //把后面小的往前面扔

                                     //这里的先进行a[i]=a[j]操作然后j+1

                                     while (i < j&&a[i] < x)

                                               i++;//从前往后面找比x大的,找到以后将其挖出来,然后后移

                                     if (i < j)

                                               a[j--] = a[i];        //把前面大的往后面扔

                            }   //这里的先进行a[j]=a[i]操作然后j-1

                            a[i] = x; //这里填写a[i]或者a[j]都可以,每循环一次有一个坑,然后将关键码填入次坑

                   quick_sort(a, l, i - 1);

                   quick_sort(a, i + 1, r);

         }

}

排序思想:(挖坑的时候指针不移动,填坑的时候,指针移动和查找顺序相反

   先规定一个枢纽,然后从右边往左边找第一个小于枢纽的然后将其取出,挖个坑,然后从左边往右边找第一个大于枢纽的,填入此坑,然后指针移动。

05希尔排序

void shellsort(int *a, int n)

{

         int dk = n / 2;

         while (dk >= 1)

         {

                   shell_insert(a, n, dk);

                   dk = dk / 2;

         }

void shell_insert(int *a, int n, int dk)

{

         int i, j;

         for (i = dk; i < n; i++)

         {

                   int key = a[i];

                   for (j = i; j>0 && a[j - dk] > key; j = j - dk)

                   {

                            a[j] = a[j - dk];

                   }

                   a[j] = key;

         }

}

排序思想:

   分组有序,然后全部有序,

建议掌握第三种:

   此种排序是插入排序的升级版

06堆排序

void creat_heap(int *a, int n)

{

         for (int i = n / 2-1; i >= 0; i--) //传递来的起始节点之前的全部遍历

         {                                  

                   int max = i;                   

                   int l = 2 * i + 1;             

                   int r = 2 * i + 2;             

                   if (l < n&&a[l]>a[max])        

                   {                                                                        

                            max = l;                   

                   }                                                                        

                   if (ra[max])                                

                   {

                            max = r;

                   }

                   if (max != i)              {

                            swap(a[max], a[i]);//执行到此处完成对三个数字的比较

                   }

         }

}

void heap_sort(int *a, int n)

{

    creat_heap(a, n);//先创建一个顶堆,然后就可以进行换序

         for (int i = n - 1; i > 0; i--) //在此处要遍历(n-1)次

         {  //在此处交换位置,执行的是上次创建堆的结果

                   swap(a[0], a[i]);

                   creat_heap(a, i);

                   Print(a, n);   

         }

}

07归并排序

void MergeArray(int a[], int l, int mid, int r)

{

         int m = mid;

         int n = r;

         int i = l;

         int j = mid + 1;

         int k = 0;

         int tmp[N] = { 0 };

         while (i <= m &&j <= n)

         {

                   if (a[i] <= a[j])

                   {

                            tmp[k++] = a[i++];

                   }

                   else

                   {

                            tmp[k++] = a[j++];

                   }

         }

         while (i <= m)

         {

                   tmp[k++] = a[i++];

         }

         while (j <= n)

         {

                   tmp[k++] = a[j++];

         }

         for (i = 0; i

                   a[ l+i] = tmp[i];

}

void mergesort(int a[], int l, int r)

{

         if (l < r)

         {

                   int mid = (l + r) / 2;

                   mergesort(a, l, mid);

                   mergesort(a, mid + 1, r);

                   MergeArray(a, l, mid, r);

         }

}

08基数排序

//(2)LSD法实现

//最低位优先法首先依据最低位关键码Kd对所有对象进行一趟排序,

//再依据次低位关键码Kd - 1对上一趟排序的结果再排序,

//依次重复,直到依据关键码K1最后一趟排序完成,就可以得到一个有序的序列。

//使用这种排序方法对每一个关键码进行排序时,不需要再分组,而是整个对象组。

#include

#include

using namespace std;

#define   MAXSIZE   10000

#define     N  sizeof(br)/sizeof(*br)

int getdigit(int x, int d)  //取数组内容的个位数字

{

         int a[] = { 1, 10, 100 };   //最大三位数,所以这里只要百位就满足了。

         return (x / a[d]) % 10;     //依次取值个位 十位 百位

}

void  PrintArr(int ar[], int n)

{

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

         {

                   cout << ar[i] << " ";

         }

         cout << endl;

}

void lsdradix_sort(int arr[], int begin, int end, int d)

{

         const int radix = 10;  //桶的个数不许修改

         int count[radix], i, j;

         int *bucket = (int*)malloc((end - begin + 1)*sizeof(int));  //所有桶的空间开辟//按照分配标准依次进行排序过程

         for (int k = 1; k <= d; k++)//此处循环3次

         {

                   for (i = 0; i < radix; i++)     //置空

                   {count[i] = 0;}

                   for (i = begin; i <= end; i++)      //统计编号为0-9的桶中所盛数据个数

                   {count[getdigit(arr[i], k)]++;}

                   for (i = 1; i < radix; i++)  //count[i]表示第i个桶的右边界索引

                   {count[i] = count[i] + count[i - 1];} //这里应该是分别建立编号为0-9的右边界

                   //把数据依次装入桶(注意装入时候的分配技巧)

                   for (i = end; i >= begin; i--)        //这里要从右向左扫描,保证排序稳定性  

                   {

                            j = getdigit(arr[i], k);        //求出关键码的第k位的数字 

                            bucket[count[j] - 1] = arr[i];//这里是放到编号对应位置右边界依次往里面放

                            count[j]--;               //对应桶的装入数据索引减一 

                   }

                   //注意:此时count[i]为第i个桶左边界 

                   //从各个桶中收集数据

                   for (i = begin, j = 0; i <= end; i++, j++)

                   {

                            arr[i] = bucket[j];

                   }

         }

         free(bucket);

}

void  main()

{

         int  br[] = { 20, 80, 90,313,423,356,734, 998, 965, 852, 123, 456, 789 };

         cout << "原数据如下:" << endl;

         PrintArr(br, N);

         lsdradix_sort(br, 0,N-1, 3); //数组+数组边界+数组位数

         cout << "排序后数据如下:" << endl;

         PrintArr(br, N);

}

排序思想:

例如按照低位排序,首先从左向右边统计0-9的数字个数。然后从左边向右边确定0-9数字在中间数组中的位置(确定右边界),然后从右边往左边遍历,放入桶中对应位置,右边界索引减1。然后把中间数组中的内容放到初始数组中。在释放中间数组

在申请数组的时候,得到一个连续类型的数据块和初始地址的时候,就可以按照数组的形式进行操作。

时间复杂度:d(n+r) d代表长度r代表关键字的基数。n代表关键字的个数

思路来源:网络上其他文章。


 

你可能感兴趣的:(八大排序,C++,算法)