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;
}
}
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;
}
}
};