LeetCode随笔之排序算法

来源:互联网 发布:不同域名的区别 编辑:程序博客网 时间:2024/06/05 11:53
  1. 快速排序
void quicksort(int A[],int l,int r){    if(l<r)    {        int i=l;        int j=r;        int x=A[l];        //while循环保证把第一个数A提出来,把从右往左数的比A小的放到A的坑里;        //把从左往右数比A大的放到右边空出来的坑里;        //一次循环结束后,把A放到中间的坑里。        while(i<j){            while(A[j]>x && i<j){                j--;            }            if(i<j)//这步重要啊,要判定。                A[i++]=A[j];//i先参与计算,再自加1            while(A[i]<x && i<j){                i++;            }            if(i<j)                A[j--]=A[i];        }        A[j]=x;        quicksort(A,l,i-1);        quicksort(A,i+1,r);    }}
  1. 快速排序之单链表实现
//快速排序之单链表实现O(nlogn);struct listNode{    int val;    listNode* next;    listNode(int val):val(val),next(NULL){}};listNode* getPartion(listNode* begin,listNode* end){    int val=begin->val;    listNode *p=begin;    listNode *q=p->next;    while(q!=end){        if(q->val<val){            p=p->next;            swap(p->val,q->val);        }        q=q->next;    }    swap(p->val,begin->val);    return p;}void quickSortList(listNode* begin,listNode *end){    if(begin!=end){        listNode* partion=getPartion(begin, end);        quickSortList(begin,partion);        quickSortList(partion->next,end);    }}
  1. 希尔排序
void shellsort(int A[],int n){    for(int gap=n/2;gap>0;gap/=2){        for(int i=gap;i<n;i++){            if(A[i]<A[i-gap]){                int tmp=A[i];                int k=i-gap;                //这是插入排序,插入就是比tmp大的值逐一向后,直到碰到不比tmp大的值,插入                while(k>=0 && A[k]>tmp){                     A[k+gap]=A[k];                    k-=gap;                }                A[k+gap]=tmp;            }        }    }    for(int i=0;i<n;i++){        printf("%d ",A[i]);    }}
  1. 归并排序
void merge(vector<int>& A,int left,int mid,int right){    int i=left;int j=mid+1;    int k=0;    vector<int> tmp(right-left+1);    while(i<=mid&&j<=right){        if(A[i]<A[j])            tmp[k++]=A[i++];        else             tmp[k++]=A[j++];    }    while(i<=mid)//注意这个地方逐个将剩下的值赋给tmp        tmp[k++]=A[i++];    while(j<=right)        tmp[k++]=A[j++];    for(int i=left,j=0;i<=right;i++,j++){//注意这个地方赋值的索引        A[i]=tmp[j];    }}void mergeSort(vector<int> &A,int left,int right){    if(left==right)return;//attention    int mid=(left+right)/2;    mergeSort(A,left,mid);    mergeSort(A,mid+1,right);//attention mid+1    merge(A,left,mid,right);}
  1. 链表的归并排序
class Solution {public:    ListNode* sortList(ListNode* head) {        if(head==NULL || head->next==NULL)return head;        ListNode *p=head;ListNode *q=p;        while(q->next!=NULL && q->next->next!=NULL){            p=p->next;            q=q->next->next;        }        ListNode* mid=p->next;        p->next=NULL;//截断链表        head=sortList(head);//将新顺序的链表返回head        mid=sortList(mid);//将新顺序的链表返回mid        return mergeList(head,mid);    }    ListNode *mergeList(ListNode* head,ListNode* mid){        ListNode* newList=new ListNode(0);//似乎链表头部没办法赋值,实际上从链表第二个指针        //开始赋值的        ListNode* newHead=newList;        while(head && mid){            if(head->val<mid->val){                newList->next=head;                head=head->next;            }            else{                newList->next=mid;                mid=mid->next;            }            newList=newList->next;        }        while(head){            newList->next=head;            head=head->next;newList=newList->next;        }        while(mid){            newList->next=mid;            mid=mid->next;newList=newList->next;        }        return newHead->next;//由于第一个指针是没用的,所以从第二个指针开始返回。    }};