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; }//如果关键字大于前面的那个就直接插入 } |
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; } } |
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; //相邻两个进行比较,然后向后移动 } } } } |
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); } } 排序思想:(挖坑的时候指针不移动,填坑的时候,指针移动和查找顺序相反) 先规定一个枢纽,然后从右边往左边找第一个小于枢纽的然后将其取出,挖个坑,然后从左边往右边找第一个大于枢纽的,填入此坑,然后指针移动。 |
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; } } 排序思想: 分组有序,然后全部有序, 建议掌握第三种: 此种排序是插入排序的升级版 |
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 (r { 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); } } |
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); } } |
//(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代表关键字的个数 思路来源:网络上其他文章。 |