1.希尔排序 shellsort
增量序列d = {n/2 ,n/4, n/8 .....1} n为要排序数的个数
void ShellInsertSort(int a[], int n, int dk) //n个要排序的数,dk是增量 { for(int i= dk; i<n; ++i){ if(a[i] < a[i-dk]){ //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入 int j = i-dk; int x = a[i]; //复制为哨兵,即存储待排序元素 a[i] = a[i-dk]; //首先后移一个元素 while(x < a[j]){ //查找在有序表的插入位置 a[j+dk] = a[j]; j -= dk; //元素后移 } a[j+dk] = x; //插入到正确位置 } print(a, n,i ); } }
void shellSort(int a[], int n){ int dk = n/2; while( dk >= 1 ){ ShellInsertSort(a, n, dk); dk = dk/2; } }
/** * 已知H[s…m]除了H[s] 外均满足堆的定义 * 调整H[s],使其成为大顶堆.即将对第s个结点为根的子树筛选, * * @param H是待调整的堆数组 * @param s是待调整的数组元素的位置 * @param length是数组的长度 * */ void HeapAdjust(int H[],int s, int length) { int tmp = H[s]; int child = 2*s+1; //左孩子结点的位置。(i+1 为当前调整结点的右孩子结点的位置) while (child < length) { if(child+1 <length && H[child]<H[child+1]) { // 如果右孩子大于左孩子(找到比当前待调整结点大的孩子结点) ++child ; } if(H[s]<H[child]) { // 如果较大的子结点大于父结点 H[s] = H[child]; // 那么把较大的子结点往上移动,替换它的父结点 s = child; // 重新设置s ,即待调整的下一个结点的位置 child = 2*s+1; } else { // 如果当前待调整结点大于它的左右孩子,则不需要调整,直接退出 break; } H[s] = tmp; // 当前待调整的结点放到比其大的孩子结点位置上 } print(H,length); } /** * 初始堆进行调整 * 将H[0..length-1]建成堆 * 调整完之后第一个元素是序列的最小的元素 */ void BuildingHeap(int H[], int length) { //最后一个有孩子的节点的位置 i= (length -1) / 2 for (int i = (length -1) / 2 ; i >= 0; --i) HeapAdjust(H,i,length); } /** * 堆排序算法 */ void HeapSort(int H[],int length) { //初始堆 BuildingHeap(H, length); //从最后一个元素开始对序列进行调整 for (int i = length - 1; i > 0; --i) { //交换堆顶元素H[0]和堆中最后一个元素 int temp = H[i]; H[i] = H[0]; H[0] = temp; //每次交换堆顶元素和堆中最后一个元素之后,都要对堆进行调整 HeapAdjust(H,0,i); } }
3、归并排序,这里用到的是Leetcode里面的题作为例子来说明
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ //归并 class Solution { public: ListNode* sortList(ListNode* head) { return mergesort(head); } ListNode* merge(ListNode *lh,ListNode *rh) //归并两个链表 { ListNode *p; p = (struct ListNode *)malloc(sizeof(struct ListNode)); ListNode *temp=p; while(lh!=NULL&&lh!=NULL) { if(lh->val<=rh->val) { p->next=lh; lh=lh->next; } if(lh->val>rh->val) { p->next=rh; rh=rh->next; } p=p->next; } if(lh!=NULL) p->next=lh; if(rh!=NULL) p->next=rh; temp=temp->next; return temp; } ListNode* mergesort(ListNode* head) //归并排序 { if(head==NULL||head->next==NULL) return head; ListNode *p=head,*q=head,*pre=NULL; //ListNode *t=pre; while(q!=NULL&&q->next!=NULL) { q=q->next->next; //q是索引,取半 pre=p; p=p->next; } pre->next=NULL; ListNode *lhalf=mergesort(head); ListNode *rhalf=mergesort(p); return merge(lhalf,rhalf); } };
3、插入排序,也是用的Leetcode里面的题
我的思路:题目中是以链表的形式给出的,由于链表很难操作,我先将链表里的数据放在vector容器里,将容器里的序列进行排序,然后再转换成链表的形式。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* insertionSortList(ListNode* head) { ListNode* p=head; //p = (struct ListNode *)malloc(sizeof(struct ListNode)); ListNode* res=p; if(head==NULL||head->next==NULL) return head; else { vector<int> a; while(head!=NULL) { a.push_back(head->val); head=head->next; } for(int i=1,j;i<a.size();i++) { int t=a[i]; for(j=i;j>0&&t<a[j-1];j--) { a[j]=a[j-1]; } a[j]=t; } for(int i=0;i<a.size();i++) { p->val=a[i]; p=p->next; } return res; } } };