• 排序算法---链表排序


    前言

      链表排序思想和数组排序类似,区别就是数组遍历容易,数据交换也容易;链表(单项链表)只能一个方向遍历,不能逆序遍历(也可以先反转在遍历),且不能随机访问,所以排序比较麻烦,同时链表的数据交换也很麻烦,如果交换两个节点,需要共涉及3个节点,无形中增加了复杂度,也可以直接交换节点中的数据,这种方式相对简单。

      如下列出了几种相对比较好简单也好理解的链表排序算法,代码如下:

      1 #include <iostream>
      2 
      3 using namespace std;
      4 
      5 struct Node
      6 {
      7     struct Node *next;
      8     int data;
      9 };
     10 
     11 Node *createNode(int x)
     12 {
     13     Node *p = NULL;
     14     
     15     p = new Node;
     16     p->next = NULL;
     17     p->data = x;
     18     
     19     return p;
     20 }
     21 
     22 void addNode(Node **head, Node *p)
     23 {
     24     Node *temp = NULL;
     25     if(*head == NULL)
     26     {
     27         *head = p;
     28     }
     29     else
     30     {
     31         temp = *head;
     32         while(temp->next != NULL)
     33         {
     34             temp = temp->next;
     35         }
     36         temp->next = p;
     37     }
     38 }
     39 
     40 void showList(Node *head)
     41 {
     42     while(head != NULL)
     43     {
     44         cout << head->data << "  ";
     45         head = head->next;
     46     }
     47     cout << endl;
     48 }
     49 
     50 void swap(int& a, int& b)
     51 {
     52     int tmp = b;
     53     b = a;
     54     a = tmp;
     55 }
     56 
     57 // 1. 直接选择排序   ------直接交换数据
     58 void ListSort_1(Node **head)
     59 {
     60     Node *p = NULL;
     61     Node *q = NULL;
     62     Node *t = NULL;
     63     
     64     if(*head == NULL || (*head)->next == NULL)
     65     {
     66         return;
     67     }
     68 
     69     for(p = *head; p != NULL; p = p->next)
     70     {
     71         t = p;
     72         
     73         for(q = p->next; q != NULL; q = q->next)
     74         {
     75             if(q->data < t->data)
     76             {
     77                 t = q;
     78             }
     79         }
     80         
     81         if(t != p)
     82         {
     83             swap(p->data, t->data);
     84         }
     85     }
     86     
     87     return;
     88 }
     89 
     90 // 2. 冒泡排序     ------直接交换数据
     91 void ListSort_2(Node **head)
     92 {
     93     Node *p = NULL;
     94     Node *q = NULL;
     95     Node *t = NULL;
     96     
     97     if(*head == NULL || (*head)->next == NULL)
     98     {
     99         return;
    100     }
    101 
    102     for(p = *head; p != NULL; p = p->next)
    103     {
    104         for(q = *head; q->next != NULL; q = q->next)
    105         {
    106             if(q->data > q->next->data)
    107             {
    108                 swap(q->data, q->next->data);
    109             }
    110         }
    111         
    112     }
    113 }
    114 
    115 // 3. 插入排序
    116 void ListSort_3(Node **head)
    117 {
    118     //直接插入排序涉及到链表的反向遍历,比较麻烦,不建议
    119 }
    120 
    121 Node *merge(Node *left, Node *right)
    122 {
    123     Node *head = createNode(-1);  // 小技巧
    124     Node *temp = head;
    125     
    126     while(left != NULL && right != NULL)
    127     {
    128         if(left->data < right->data)
    129         {
    130             temp->next = left;
    131             temp = temp->next;
    132             left = left->next;
    133         }
    134         else
    135         {
    136             temp->next = right;
    137             temp = temp->next;
    138             right = right->next;
    139         }
    140     }
    141     
    142     if(left != NULL)
    143     {
    144         temp->next = left;
    145     }
    146     
    147     if(right != NULL)
    148     {
    149         temp->next = right;
    150     }
    151     
    152     return head->next;
    153 }
    154 
    155 Node *_ListSort_4(Node *head)
    156 {
    157     Node *pFast = NULL;
    158     Node *pSlow = NULL;
    159     Node *mid = NULL;
    160     
    161     if(head == NULL || head->next == NULL)
    162     {
    163         return head;
    164     }
    165     
    166     pFast = head;
    167     pSlow = head;
    168     
    169     while(pFast->next != NULL && pFast->next->next != NULL)
    170     {
    171         pFast = pFast->next->next;
    172         pSlow = pSlow->next;
    173     }
    174     
    175     mid = pSlow->next;
    176     pSlow->next = NULL;
    177     
    178     return merge(_ListSort_4(head), _ListSort_4(mid));
    179 }
    180 
    181 // 4. 归并排序      ------交换节点
    182 void ListSort_4(Node **head)
    183 {
    184     Node *temp = *head;
    185     *head = _ListSort_4(temp);
    186 }
    187 
    188 int main()
    189 {
    190     Node *head = NULL;
    191     
    192     addNode(&head, createNode(2));
    193     addNode(&head, createNode(5));
    194     addNode(&head, createNode(7));
    195     addNode(&head, createNode(4));
    196     addNode(&head, createNode(6));
    197     addNode(&head, createNode(3));
    198     addNode(&head, createNode(1));
    199     addNode(&head, createNode(9));
    200     addNode(&head, createNode(8));
    201 
    202     cout << "Sort Before:" << endl;
    203     showList(head);
    204     
    205     //ListSort_1(&head);
    206     //ListSort_2(&head);
    207     ListSort_4(&head);
    208     
    209     cout << "Sort After:" << endl;
    210     showList(head);211 
    212     while(1);
    213     return 0;
    214 }
  • 相关阅读:
    <C++ QT4 GUI 编程>第一章笔记
    生成snmp++动态库
    PHP 5.3 新特性
    编译安装-Subversion 1.8.5
    Xen入门系列四【Xen 管理实操】
    Xen入门系列三【Xen 管理工具 xm】
    COMET探索系列三【异步通知服务器关闭数据连接实现思路】
    PHP生成二维码【谷歌API+qrcode+圆角Logo】
    SSH免密码登陆详解
    COMET探索系列二【Ajax轮询复用模型】
  • 原文地址:https://www.cnblogs.com/chusiyong/p/11323354.html
Copyright © 2020-2023  润新知