當前位置: 首頁>>算法&結構>>正文


單鏈表的快速排序(原創)

單鏈表的快速排序和數組的快速排序在基本細想上是一致的,以從小到大來排序單鏈表為例,

都是選擇一個支點,然後把小於支點的元素放到左邊,把大於支點的元素放到右邊,然後分治遞歸。

但是,由於單鏈表不能像數組那樣隨機存取,和數組的快排序相比,還是有一些需要注意的細節:

1. 支點的選取,由於不能隨機訪問第K個元素,因此每次選擇支點時可以取待排序那部分鏈表的頭指針。

2. 遍曆鏈表方式,由於不能從單鏈表的末尾向前遍曆,因此使用兩個指針分別向前向後遍曆的策略失效,

事實上,可以可以采用一趟遍曆的方式將較小的元素放到單鏈表的左邊。具體方法為:

1)定義兩個指針pslow, pfast,其中pslow指單鏈表頭結點,pfast指向單鏈表頭結點的下一個結點;

2)使用pfast遍曆單鏈表,每遇到一個比支點小的元素,就和pslow進行數據交換,然後令pslow=pslow->next。

3. 交換數據方式,直接交換鏈表數據指針指向的部分,不必交換鏈表節點本身。

基於上述思想的單鏈表快排序實現如下:


#include 
#include 
using namespace std;
//單鏈表節點

struct SList
{
    int data;
    struct SList* next;
};

void bulid_slist(SList** phead, int n)
{
    SList* ptr = NULL;
    for(int i = 0; i < n; ++i)
    {
        SList* temp = new SList;
        temp->data = rand() % n;
        temp->next = NULL;
        if(ptr == NULL)
        {
            *phead = temp;
            ptr = temp;
        }
        else
        {
            ptr->next = temp;
            ptr = ptr->next;
        }
    }
}

SList* get_last_slist(SList* phead)
{
    SList* ptr = phead;
    while(ptr->next)
    {
        ptr = ptr->next;
    }
    return ptr;
}

void print_slist(SList* phead)
{
    SList* ptr = phead;
    while(ptr)
    {
        printf("%d ", ptr->data);
        ptr = ptr->next;
    }
    printf("\n");
}

void sort_slist(SList* phead, SList* pend)
{
    if(phead == NULL || pend == NULL) return;
    if(phead == pend) return;
    SList* pslow = phead;
    SList* pfast = phead->next;
    SList* ptemp = phead;
    while(pfast && pfast != pend->next)
    {
        if(pfast->data <= phead->data) //phead作為支點

        {
            ptemp = pslow;
            pslow = pslow->next;
            swap(pslow->data, pfast->data);
        }
        pfast = pfast->next;
    }
    swap(phead->data, pslow->data);

    sort_slist(phead, ptemp);//ptemp為左右兩部分分割點的前一個節點
    sort_slist(pslow->next, pend);

}

void destroy_slist(SList* phead)
{
    SList* ptr = phead;
    while(ptr)
    {
        SList* temp = ptr;
        ptr = ptr->next;
        delete temp;
    }
}

int main(int argc, char** argv)
{
    srand(time(NULL));
    printf("sort single list\n");
    SList* phead = NULL;
    bulid_slist(&phead, 100);
    print_slist(phead);
    SList* plast = get_last_slist(phead);
    printf("head:%d, last:%d\n", phead->data, plast->data);
    sort_slist(phead, plast);
    print_slist(phead);
    destroy_slist(phead);
    system("pause");
    return 0;
}
本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/94.html,未經允許,請勿轉載。