链表排序算法总结

1. 选择排序

typedef struct Node {  
    int data;  
    struct Node* next;  
} Node;  
typedef struct Node* LinkList; /* 定义LinkList */ 

LinkList selectSort(LinkList head) {  
    LinkList p,q,small;  
    int temp;  

    for(p = head; p != NULL; p = p->next) {  
        small = p;  
        for(q = p->next; q != NULL; q = q->next) {  
            if(q->data < small->data) {  
                small = q;  
            }  
        }  
        printf("循环后,获得最小值为:%d, 此时链表为:", small->data);  
        if(small != p)  {  
            temp = p->data;  
            p->data = small->data;  
            small->data = temp;  
        }  
    }  
    return head;  
}  

2. 冒泡排序

void bubbleSort(LinkList head) {  
    LinkList f, p;
    int temp;  
    f = NULL;  
    //判断是否只有一个元素或者没有元素  
    if(head == NULL || head->next == NULL)  
        return;    
    bool isChange = true;
    while(f != head->next && isChange) {  
        //外层是N - 1次循环
        isChange = false; 
        for(p = head; p->next != f; p = p->next) {  
            if(p->data > p->next->data)  {  
                 temp = p->data;
                 p->data = p->next->data;
                 p->next-data = temp;
                 isChange = true;
            }  
        }  
        f = p;  
    }  
}  

3. 插入排序

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    /**
     *插入排序的思想
     *但要注意节点的操作
     */
    public ListNode insertionSortList(ListNode head){

        if(head == null || head.next == null)
            return head;

        ListNode dummy = new ListNode(Integer.MIN_VALUE);
        dummy.next  = head;
        ListNode cur = dummy;
        while(cur.next != null){
            if(cur.next.val >= cur.val) {
                cur = cur.next;
            }else {
                cur = insert(dummy, cur, cur.next);
            }
        }

        return dummy.next;
    }

    /**
     *执行插入过程
     *要找到大于node值的前一个节点
     */
    public ListNode insert(ListNode head, ListNode tail, ListNode node){

        ListNode cur = head;
        //稳定的排序 <=
        while(cur.next.val <= node.val)
            cur = cur.next;
        //注意顺序
        tail.next = node.next;
        node.next = cur.next;
        cur.next = node;

        return tail;
    }
}

4. 归并排序(Nice)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
public class Solution {
    public ListNode sortList(ListNode head) {
        if(head == null || head.next == null)
            return head;

        //找中点
        ListNode slow = head, fast = head;
        while(fast.next != null && (fast.next.next != null)) {
            slow = slow.next;
            fast = fast.next.next;
        }

        ListNode left = head;
        ListNode middlle = slow.next;
        //切断关系
        slow.next = null;

        return merge(sortList(left), sortList(middlle));
    }

     /**
     * 合并两个有序链表
     */
    public ListNode merge(ListNode head1, ListNode head2){

        ListNode dummy = new ListNode(-1);
        //dummy.next = null;
        ListNode cur = dummy;
        while(head1 != null && (head2 != null)){
            ListNode min;
            if(head1.val <= head2.val){
                min = head1;
                head1 = head1.next;
            }else {
                min = head2;
                head2 = head2.next;
            }
            cur.next = min;
            cur = min;
        }
        if(head1 != null)
            cur.next = head1;
        if(head2 != null)
            cur.next = head2;

        return dummy.next;
    }
}

5. 快速排序

    ListNode* quickSortList(ListNode* head) {
        //链表快速排序
        if(head == NULL || head->next == NULL)return head;
        qsortList(head, NULL);
        return head;
    }
    void qsortList(ListNode* head, ListNode* tail) {
        //链表范围是[low, high)
        if(head != tail && head->next != tail) {
            ListNode* mid = partitionList(head, tail);
            qsortList(head, mid);
            qsortList(mid->next, tail);
        }
    }
    /*
    我们只需要两个指针p和q,移动的过程中保持p之前的key都小于选定的key,p和q之间的key都大于选定的key,那么当q走到末尾的时候便完成了一次划分点的寻找。
    */
    ListNode* partitionList(ListNode* low, ListNode* high) {
        //链表范围是[low, high)
        int key = low->val;
        ListNode* p = low;
        for(ListNode* q = low->next; q != high; q = q->next) {
            if(q->val < key) {
                p = p->next;
                swap(q->val, p->val);
            }
        }
        swap(p->val, low->val);
        return p;
    }

你可能感兴趣的:(算法和刷题,剑指Offer之详解,排序算法)