数据结构排序
来源:互联网 发布:三国志9最新优化伴侣 编辑:程序博客网 时间:2024/05/19 18:12
在数据结构中,排序有以下几种分类:
(1)按存储位置分为内部排序和外部排序;
(2)按排序算法或者逻辑分为插入排序、选择排序、交换排序、归并排序和基数排序;
(3)按排序结果分为升序和降序。
说到排序就可以说到稳定性。稳定性我们可以理解为:在待排序数字中的重复数据,在排序前后的相对前后位置不变。
其中,
稳定的有:直接插入排序、冒泡排序、归并排序、基数排序
不稳定的有:Shell排序、选择排序(直接选择排序、堆排序)、快速排序
直接插入排序
代码实现
#include<stdio.h>void InsertSort(int *arr, int len){ int i; int j; for (i=2;i<len;i++) { arr[0] = arr[i]; for (j=i-1;arr[j]>arr[0];j--) { arr[j + 1] = arr[j]; } arr[j + 1] = arr[0]; }}
时间复杂度 :O(n^2)
空间复杂度:O(1)
代码测试
int main(){ int arr[] = { -1,55,1,3,11,5,8,6,25,14,47}; int len = sizeof(arr) / sizeof(arr[0]); InsertSort(arr, len); return 0;}
Shell(希尔)排序
代码实现
#include<stdio.h>void Shell(int *arr, int len,int dk){ int i; int j; int tmp; for (i=dk;i<len;i++) { tmp = arr[i]; for (j=i-dk;j>=0 && arr[j]>tmp;j=j-dk) { arr[j + dk] = arr[j]; } arr[j + dk] = tmp; }}void shellSort(int *arr,int arr_len,int *dka,int dka_len){ for (int i=0;i<dka_len;i++) { Shell(arr,arr_len,dka[i]); }}
时间复杂度 :O(n^2)
空间复杂度:O(1)
函数测试
int main(){ int arr[] = { 55, 2, 44, 6, 8, 32, 46, 4, 26}; int dka[] = {5,3,1}; int arr_len = sizeof(arr) / sizeof(arr[0]); int dka_len = sizeof(dka) / sizeof(dka[0]); ShellSort(arr, arr_len, dka, dka_len); return 0;}
选择排序:
①简单选择排序
②堆排序
①代码实现
#include<stdio.h>void SelectSort(int *arr, int len){ int i; int j; int min; int tmp; for (int i=0;i<len-1;i++) { min = i; for (j=i+1;j<len;j++) { if (arr[j] < arr[min]) { min = j; } } tmp = arr[min]; arr[min] = arr[i]; arr[i] = tmp; }}
时间复杂度 :O(n^2)
空间复杂度:O(1)
函数测试
int main(){ int arr[] = {1,5,6,8,6,5,85,9,6,1}; int len = sizeof(arr) / sizeof(arr[0]); SelectSort(arr, len); return 0;}
②堆排序
大根堆(升序):父节点的数据大于子节点的数据。
父节点找子节点:i=1, 左子树 j=2*i,右子树j=2*i=1
子节点找父节点:j=5,i=j/2
小根堆:降序
代码测试
#include<stdio.h>/*找到最后一个有子节点的父节点:len/2;找到较大的子节点数与父节点上的数据比较,如果子节点上的数大于父节点的,那么将两者数据交换;调整完一遍之后将最顶端的数字与最后一个数字交换,最后一个数字不用再进入比较*/void HeapAdjust(int *arr, int i, int len){ int j; //j <= len 有左子树 for (j=2*i;j<=len;j=2*j) { if (j<len && arr[j]<arr[j + 1]) { j++; } if (arr[j] < arr[i]) { break; } arr[0] = arr[i]; arr[i] = arr[j]; arr[j] = arr[0]; i = j; }}void HeapSort(int *arr, int len){ int tmp; for (int i=len/2;i>0;i--) { HeapAdjust(arr,i,len); } for (int j=len;j>0;j--) { tmp = arr[1]; arr[1] = arr[j]; arr[j] = tmp; HeapAdjust(arr,1,j-1); }}
时间复杂度 :O(log2n)
空间复杂度:O(1)
函数测试
int main(){ int arr[] = {516,8,154,8,44,52,821,56,42}; int arr1[] = {215,48,20,8,632,8,865,1}; int len = sizeof(arr)/sizeof(arr[0]) -1; HeapSort(arr,len); return 0;}
交换排序:
①冒泡排序
②快速排序
①代码实现
#include<stdio.h>void BubbleSort(int *arr,int len){ int tmp; bool mark = false; for (int i=0;i<len-1;i++) { mark = false; for (int j=0;j<len-1-i;j++) { if (arr[j]>arr[j+1]) { tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; mark = true; } } printf("i = %d\n",i); if (!mark) { break; } }}
时间复杂度 :O(n^2)
空间复杂度:O(1)
代码测试
int main(){ int arr[] = {8,651,686,51,52,64,65,85,16,516}; int len = sizeof(arr) / sizeof(arr[0]); BubbleSort(arr, len); return 0;}
②代码实现
int Partition(int *arr,int low,int high){ int tmp = arr[low]; while(low < high) { while (low < high && arr[high] >= tmp)high--; arr[low] = arr[high]; while (low < high && arr[low] <= tmp)low++; arr[high] = arr[low]; } arr[low] = tmp; return low;}void QSort(int *arr,int low,int high){ if (low < high) { int boundKey = Partition(arr,low, high); QSort(arr, low, boundKey - 1); QSort(arr, boundKey+1, high); }}void QuickSort(int *arr,int len){ QSort(arr,0,len-1);}
时间复杂度 :O(n^2)
空间复杂度:O(nlog2n)
代码测试
int main(){ int arr[] = {65,46,548,68,19,5,6,56,569}; int len = sizeof(arr) / sizeof(arr[0]); QuickSort(arr,len); printf("\n"); return 0;}
归并排序
代码实现
#include<stdio.h>void Merge(int *arr,int *tmp,int StartIndex,int MidIndex,int EndIndex){ int i = StartIndex; int j = MidIndex + 1; int k = StartIndex; while (i != MidIndex + 1 && j != EndIndex + 1) { if (arr[i] > arr[j]) { tmp[k++] = arr[j++]; } else { tmp[k++] = arr[i++]; } } while (i != MidIndex + 1) { tmp[k++] = arr[i++]; } while (j != EndIndex + 1) { tmp[k++] = arr[j++]; } for (int i=StartIndex;i <= EndIndex; i++) { arr[i] = tmp[i]; }}void MergeSort(int *arr,int *tmp,int StartIndex,int EndIndex){ if (StartIndex < EndIndex) { int MidIndex = (StartIndex + EndIndex) / 2; MergeSort(arr,tmp,StartIndex,MidIndex); MergeSort(arr,tmp,MidIndex + 1,EndIndex); Merge(arr,tmp,StartIndex,MidIndex,EndIndex); }}
时间复杂度 :O(nlog2n)
空间复杂度:O(n)
代码测试
#define N 12int main(){ int arr[12] = {2,85,1,65,6,16,32,15,88,964,53,4}; int len = sizeof(arr) / sizeof(arr[0]); int tmp[N]; MergeSort(arr,tmp,0,len-1); return 0;}
基数排序
将待排序数列分别根据个位、十位、百位排序:
代码实现
#include<stdio.h>#include<math.h>#define N 14int FindMaxFinger(int *arr, int len)//找到最大数是几位数{ int max = arr[0]; for (int i=1;i<len;i++) { if (arr[i] > max) { max = arr[i]; } } int count = 0; while(max != 0) { max = max/10; count++; } return count;}//每个数据分别在个、十、百位上的数int FindFingerNumber(int num, int fin){ return num/(int)pow(10.0,fin) % 10;}void Radix(int *arr, int len, int fin){ int tmp[10][N] = {}; int num_fin; int count[10] = {}; for (int i=0;i<len;i++) { num_fin = FindFingerNumber(arr[i],fin); tmp[num_fin][count[num_fin]] = arr[i]; count[num_fin]++; } int index = 0; for (int i=0;i<10;i++) { for (int j=0;j<count[i];j++) { arr[index++] = tmp[i][j]; } }}void RadixSort(int *arr, int len){ int MaxFinNum = FindMaxFinger(arr,len); for (int i=0;i<MaxFinNum;i++) { Radix(arr,len,i); }}
时间复杂度 :O(d(r+n))
空间复杂度:O(rd+n)
代码测试
int main(){ int arr[N] = {5,51,3,541,351,56,5165,1,651}; int len = N; RadixSort(arr,len); return 0;}
链表排序
代码实现
#include<stdio.h>#include<stdlib.h>typedef struct Node{ int val; //有效数据长度 Node* pNext;}Node;void Init(Node **head){ *head = (Node*)malloc(sizeof(Node)); if (*head == NULL)exit(0); (*head)->pNext = NULL; (*head)->val = 0;}void Insert(Node *head, int data){ Node* pCur = head; for (int i=0;i < head->val;i++) { pCur = pCur->pNext; } Node *NewNode = (Node*)malloc(sizeof(Node)); if (NewNode != NULL) { pCur->pNext = NewNode; NewNode->pNext = NULL; NewNode->val = data; head->val++; }}void Show(Node *head){ Node *pCur = head->pNext; for (int i=0;i<head->val;i++) { printf("%d ", pCur->val); pCur = pCur->pNext; } printf("\n");}void ListSort(Node* head){ Node* pCur; Node* pAfter; for (int i = 0; i < head->val - 1; ++i) { pCur = head->pNext; pAfter = pCur->pNext; for (int j = 1; j < head->val - i; ++j) { if (pCur->val > pAfter->val) { int tmp = pCur->val; pCur->val = pAfter->val; pAfter->val = tmp; } pCur = pCur->pNext; pAfter = pAfter->pNext; } }}
代码测试
int main(){ Node* pHead; Init(&pHead); for (int i=0;i<15;i++) { Insert(pHead, rand() % 100); } ListSort(pHead); Show(pHead); return 0;}
- 数据结构-排序
- 数据结构----排序
- 数据结构 - 排序
- 数据结构--排序
- 数据结构排序
- 数据结构 排序
- 数据结构排序
- 数据结构-----排序
- 数据结构排序
- 数据结构--排序
- 数据结构 排序
- 排序 - 数据结构
- 数据结构-排序
- 数据结构 - 排序
- 【数据结构】排序
- 数据结构 - 排序
- 数据结构-排序
- 数据结构排序
- Angular2 组件样式及host
- 特征分解、奇异值分解几何意义
- 广西 2017 邀请赛 Duizi and Shunzi
- Add One Row to Tree
- 算法-二叉树遍历(递归和非递归)
- 数据结构排序
- 算法-01背包1
- 算法-01背包2
- 快速排序之分割数组
- ros_comm
- 算法学习-Bucket排序
- SQLServer--存储过程的分类
- 算法-求Factorial数列
- Palindromic Substrings