• 单链表、双链表及单链表的逆序


    参考博客:数组、单链表和双链表介绍 以及 双向链表的C/C++/Java实现

                  单向链表逆序

    一、单链表

    单链表结构如下图:

    本文中,head节点也是包含数据的,并且最后一个节点指向的指针为NULL。

    下图为单链表的删除操作:

    下图为单链表的插入操作:

    单链表的实现代码如下:

      1 #ifndef SINGLE_LINK_H
      2 #define SINGLE_LINK_H
      3 
      4 #include <iostream>
      5 using namespace std;
      6 
      7 template<class T>
      8 struct SNode
      9 {
     10 public:
     11     T data;
     12     SNode *next;
     13     SNode(){}
     14     SNode(T data, SNode *next)
     15     {
     16         this->data = data;
     17         this->next = next;
     18     }
     19 };
     20 
     21 template<class T>
     22 class SingleLink
     23 {
     24     public:
     25         SingleLink();
     26         ~SingleLink();
     27 
     28         SNode<T> *getHeadNode();
     29         void setHeadNode(SNode<T> *head);
     30         int getSize();
     31         bool isEmpty();
     32         T get(int index);
     33         T getFirst();
     34         T getLast();
     35         void insert(int index, T t);
     36         void insertFirst(T t);
     37         void appendLast(T t);
     38         void del(int index);
     39         void deleteFirst();
     40         void deleteLast();
     41 
     42     private:
     43         int count;
     44         SNode<T> *pHead;
     45         SNode<T> *getNode(int index);
     46 };
     47 
     48 template<class T>
     49 SingleLink<T>::SingleLink() : count(0)
     50 {
     51     pHead = new SNode<T>();
     52     pHead->next = NULL;
     53 }
     54 
     55 template<class T>
     56 SingleLink<T>::~SingleLink()
     57 {
     58     SNode<T> *ptmp;
     59     while(pHead->next != NULL)
     60     {
     61         ptmp = pHead;
     62         pHead = pHead->next;
     63         delete ptmp;
     64     }
     65 
     66     delete pHead;
     67     pHead = NULL;
     68 }
     69 
     70 template<class T>
     71 int SingleLink<T>::getSize()
     72 {
     73     return count;
     74 }
     75 
     76 template<class T>
     77 bool SingleLink<T>::isEmpty()
     78 {
     79     return count == 0;
     80 }
     81 
     82 template<class T>
     83 SNode<T> *SingleLink<T>::getNode(int index)
     84 {
     85     if(index < 0 || index >= count)
     86     {
     87         cout << "Get node failed! The index in out of bound!" << endl;
     88         return NULL;
     89     }
     90 
     91     SNode<T> *pindex = pHead;
     92     int i = 0;
     93     while(i++ < index)
     94     {
     95         pindex = pindex->next;
     96     }
     97 
     98     return pindex;
     99 }
    100 
    101 template<class T>
    102 SNode<T> *SingleLink<T>::getHeadNode()
    103 {
    104     return getNode(0);
    105 }
    106 
    107 template<class T>
    108 void SingleLink<T>::setHeadNode(SNode<T> *head)
    109 {
    110     this->pHead = head;
    111 }
    112 
    113 template<class T>
    114 T SingleLink<T>::get(int index)
    115 {
    116     return getNode(index)->data;
    117 }
    118 
    119 template<class T>
    120 T SingleLink<T>::getFirst()
    121 {
    122     return getNode(0)->data;
    123 }
    124 
    125 template<class T>
    126 T SingleLink<T>::getLast()
    127 {
    128     return getNode(count - 1)->data;
    129 }
    130 
    131 template<class T>
    132 void SingleLink<T>::insert(int index, T t)
    133 {
    134     SNode<T> *pnode;
    135 
    136     if(index == 0)
    137     {
    138         insertFirst(t);
    139     }
    140     else if(index == count)
    141     {
    142         appendLast(t);
    143     }
    144     else
    145     {
    146         SNode<T> *pindex = getNode(index - 1);
    147         pnode = new SNode<T>(t, pindex->next);
    148         pnode->data = t;
    149         pindex->next = pnode;
    150         count++;
    151     }
    152 }
    153 
    154 template<class T>
    155 void SingleLink<T>::insertFirst(T t)
    156 {
    157     if(count == 0)
    158     {
    159         pHead->data = t;
    160     }
    161     else
    162     {
    163         SNode<T> *pnode = new SNode<T>(t, pHead);
    164         pHead = pnode;
    165     }
    166     count++;
    167 }
    168 
    169 template<class T>
    170 void SingleLink<T>::appendLast(T t)
    171 {
    172     SNode<T> *pindex = getNode(count - 1);
    173     SNode<T> *pnode = new SNode<T>();
    174     pindex->next = pnode;
    175     pnode->data = t;
    176     pnode->next = NULL;
    177     count++;
    178 }
    179 
    180 template<class T>
    181 void SingleLink<T>::del(int index)
    182 {
    183     if(index >= count)
    184     {
    185         cout << "The index in out of bound!" << endl;
    186     }
    187     else
    188     {
    189         SNode<T> *pindex = getNode(index - 1);
    190         SNode<T> *ptmp = pindex->next;
    191         pindex->next = pindex->next->next;
    192         delete ptmp;
    193         ptmp = NULL;
    194         count--;
    195     }
    196 }
    197 
    198 template<class T>
    199 void SingleLink<T>::deleteFirst()
    200 {
    201     if(count == 0)
    202     {
    203         cout << "This single link is null!";
    204         return;
    205     }
    206     SNode<T> *ptmp = pHead;
    207     pHead = pHead->next;
    208     delete ptmp;
    209     ptmp = NULL;
    210     count--;
    211 }
    212 
    213 template<class T>
    214 void SingleLink<T>::deleteLast()
    215 {
    216     del(count - 1);
    217 }
    218 
    219 #endif
    View Code

    测试代码如下:

      1 #include <iostream>
      2 #include <string>
      3 #include "DoubleLink.h"
      4 #include "SingleLink.h"
      5 using namespace std;
      6 
      7 void IntTest()
      8 {
      9     cout << "
    ----IntTest----" << endl;
     10 
     11     SingleLink<int> *pdlink = new SingleLink<int>();
     12 
     13     pdlink->insert(0, 20);
     14     pdlink->appendLast(10);
     15     pdlink->insertFirst(30);
     16 
     17     cout << "isEmpty() = " << pdlink->isEmpty() << endl;
     18 
     19     cout << "size() = " << pdlink->getSize() << endl;
     20 
     21     int sz = pdlink->getSize();
     22     for(int i = 0; i < sz; i++)
     23     {
     24         cout << "pdlink(" << i << ") = " << pdlink->get(i) << endl;
     25     }
     26 
     27     delete pdlink;
     28 }
     29 
     30 void StringTest()
     31 {
     32     cout << "
    ----StringTest----" << endl;
     33 
     34     string sarr[3] = {"ten", "twenty", "thirty"};
     35 
     36     SingleLink<string> *pdlink = new SingleLink<string>();
     37 
     38     pdlink->insert(0, sarr[0]);
     39     pdlink->appendLast(sarr[1]);
     40     pdlink->insertFirst(sarr[2]);
     41 
     42     cout << "isEmpty() = " << pdlink->isEmpty() << endl;
     43 
     44     cout << "size() = " << pdlink->getSize() << endl;
     45 
     46     int sz = pdlink->getSize();
     47     for(int i = 0; i < sz; i++)
     48     {
     49         cout << "pdlink(" << i << ") = " << pdlink->get(i) <<endl;
     50     }
     51 
     52     delete pdlink;
     53 }
     54 
     55 struct stu
     56 {
     57     int id;
     58     char name[20];
     59 };
     60 
     61 static stu arr_stu[] =
     62 {
     63     {10, "sky"},
     64     {20, "jody"},
     65     {30, "vic"},
     66 };
     67 
     68 void ObjectTest()
     69 {
     70     cout << "
    ----ObjectTest----" << endl;
     71 
     72     SingleLink<stu> *pdlink = new SingleLink<stu>();
     73 
     74     pdlink->insert(0, arr_stu[0]);
     75     pdlink->appendLast(arr_stu[1]);
     76     pdlink->insertFirst(arr_stu[2]);
     77 
     78     cout << "isEmpty() = " << pdlink->isEmpty() << endl;
     79 
     80     cout << "size() = " << pdlink->getSize() << endl;
     81 
     82     int sz = pdlink->getSize();
     83     struct stu p;
     84     for(int i = 0; i < sz; i++)
     85     {
     86         p = pdlink->get(i);
     87         cout << "pdlink(" << i << ") = [" << p.id << ", " << p.name << "]" << endl;
     88     }
     89 
     90     delete pdlink;
     91 }
     92 
     93 int main()
     94 {
     95     IntTest();
     96     StringTest();
     97     ObjectTest();
     98 
     99     return 0;
    100 }
    View Code

    二、双链表

    双链表的结构如下:

    本文的实现中,head节点作为一个特殊节点,不存储数据。

    下图为双链表的删除操作:

    下图为双链表的插入操作:

    双链表的实现代码如下:

      1 #ifndef DOUBLE_LINK_H
      2 #define DOUBLE_LINK_H
      3 
      4 #include <iostream>
      5 using namespace std;
      6 
      7 template<class T>
      8 struct DNode
      9 {
     10     public:
     11         T value;
     12         DNode *prev;
     13         DNode *next;
     14     public:
     15         DNode(){}
     16         DNode(T t, DNode *prev, DNode *next)
     17         {
     18             this->value = t;
     19             this->prev  = prev;
     20             this->next  = next;
     21         }
     22 };
     23 
     24 template<class T>
     25 class DoubleLink
     26 {
     27     public:
     28         DoubleLink();
     29         ~DoubleLink();
     30 
     31         int getSize();
     32         int isEmpty();
     33 
     34         T get(int index);
     35         T getFirst();
     36         T getLast();
     37 
     38         int insert(int index, T t);
     39         int insertFirst(T t);
     40         int appendLast(T t);
     41 
     42         int del(int index);
     43         int deleteFirst();
     44         int deleteLast();
     45 
     46     private:
     47         int count;
     48         DNode<T> *pHead;
     49     private:
     50         DNode<T> *getNode(int index);
     51 };
     52 
     53 template<class T>
     54 DoubleLink<T>::DoubleLink() : count(0)
     55 {
     56     pHead = new DNode<T>();
     57     pHead->prev = pHead->next = pHead;
     58     //count = 0;
     59 }
     60 
     61 template<class T>
     62 DoubleLink<T>::~DoubleLink()
     63 {
     64     DNode<T> *ptmp;
     65     DNode<T> *pnode = pHead->next;
     66     while(pnode != pHead)
     67     {
     68         ptmp = pnode;
     69         pnode = pnode->next;
     70         delete ptmp;
     71     }
     72 
     73     delete pHead;
     74     pHead = NULL;
     75 }
     76 
     77 template<class T>
     78 int DoubleLink<T>::getSize()
     79 {
     80     return count;
     81 }
     82 
     83 template<class T>
     84 int DoubleLink<T>::isEmpty()
     85 {
     86     return count == 0;
     87 }
     88 
     89 template<class T>
     90 DNode<T> *DoubleLink<T>::getNode(int index)
     91 {
     92     if(index < 0 || index >= count)
     93     {
     94         cout << "Get node failed! The index in out of bound!" << endl;
     95         return NULL;
     96     }
     97 
     98     if(index <= count/2)
     99     {
    100         int i = 0;
    101         DNode<T> *pindex = pHead->next;
    102         while(i++ < index)
    103         {
    104             pindex = pindex->next;
    105         }
    106 
    107         return pindex;
    108     }
    109 
    110     int j = 0;
    111     int lindex = count - index -1;
    112     DNode<T> *prindex = pHead->prev;
    113     while(j++ < lindex)
    114     {
    115         prindex = prindex->prev;
    116     }
    117 
    118     return prindex;
    119 }
    120 
    121 template<class T>
    122 T DoubleLink<T>::get(int index)
    123 {
    124     return getNode(index)->value;
    125 }
    126 
    127 template<class T>
    128 T DoubleLink<T>::getFirst()
    129 {
    130     return getNode(0)->value;
    131 }
    132 
    133 template<class T>
    134 T DoubleLink<T>::getLast()
    135 {
    136     return getNode(count - 1)->value;
    137 }
    138 
    139 template<class T>
    140 int DoubleLink<T>::insert(int index, T t)
    141 {
    142     if(index == 0)
    143     {
    144         return insertFirst(t);
    145     }
    146 
    147     DNode<T> *pindex = getNode(index);
    148     DNode<T> *pnode  = new DNode<T>(t, pindex->prev, pindex);
    149     pindex->prev->next = pnode;
    150     pindex->prev = pnode;
    151     count++;
    152 
    153     return 0;
    154 }
    155 
    156 template<class T>
    157 int DoubleLink<T>::insertFirst(T t)
    158 {
    159     DNode<T> *pnode   = new DNode<T>(t, pHead, pHead->next);
    160     pHead->next->prev = pnode;
    161     pHead->next = pnode;
    162     count++;
    163 
    164     return 0;
    165 }
    166 
    167 template<class T>
    168 int DoubleLink<T>::appendLast(T t)
    169 {
    170     DNode<T> *pnode   = new DNode<T>(t, pHead->prev, pHead);
    171     pHead->prev->next = pnode;
    172     pHead->prev = pnode;
    173     count++;
    174 
    175     return 0;
    176 }
    177 
    178 template<class T>
    179 int DoubleLink<T>::del(int index)
    180 {
    181     DNode<T> *pindex   = getNode(index);
    182     pindex->next->prev = pindex->prev;
    183     pindex->prev->next = pindex->next;
    184     delete pindex;
    185     count--;
    186 
    187     return 0;
    188 }
    189 
    190 template<class T>
    191 int DoubleLink<T>::deleteFirst()
    192 {
    193     DNode<T> *temp = pHead;
    194     pHead->next->prev = pHead->prev;
    195     pHead->prev->next = pHead->next;
    196     pHead = pHead->next;
    197     count--;
    198     delete temp;
    199 
    200     return 0;
    201 }
    202 
    203 template<class T>
    204 int DoubleLink<T>::deleteLast()
    205 {
    206     return del(count-1);
    207 }
    208 
    209 #endif
    View Code

    测试代码如下:

      1 #include <iostream>
      2 #include <string>
      3 #include "DoubleLink.h"
      4 #include "SingleLink.h"
      5 using namespace std;
      6 
      7 void IntTest()
      8 {
      9     cout << "
    ----IntTest----" << endl;
     10 
     11     DoubleLink<int> *pdlink = new DoubleLink<int>();
     12 
     13     pdlink->insert(0, 20);
     14     pdlink->appendLast(10);
     15     pdlink->insertFirst(30);
     16 
     17     cout << "isEmpty() = " << pdlink->isEmpty() << endl;
     18 
     19     cout << "size() = " << pdlink->getSize() << endl;
     20 
     21     int sz = pdlink->getSize();
     22     for(int i = 0; i < sz; i++)
     23     {
     24         cout << "pdlink(" << i << ") = " << pdlink->get(i) << endl;
     25     }
     26 
     27     delete pdlink;
     28 }
     29 
     30 void StringTest()
     31 {
     32     cout << "
    ----StringTest----" << endl;
     33 
     34     string sarr[3] = {"ten", "twenty", "thirty"};
     35 
     36     DoubleLink<string> *pdlink = new DoubleLink<string>();
     37 
     38     pdlink->insert(0, sarr[0]);
     39     pdlink->appendLast(sarr[1]);
     40     pdlink->insertFirst(sarr[2]);
     41 
     42     cout << "isEmpty() = " << pdlink->isEmpty() << endl;
     43 
     44     cout << "size() = " << pdlink->getSize() << endl;
     45 
     46     int sz = pdlink->getSize();
     47     for(int i = 0; i < sz; i++)
     48     {
     49         cout << "pdlink(" << i << ") = " << pdlink->get(i) <<endl;
     50     }
     51 
     52     delete pdlink;
     53 }
     54 
     55 struct stu
     56 {
     57     int id;
     58     char name[20];
     59 };
     60 
     61 static stu arr_stu[] =
     62 {
     63     {10, "sky"},
     64     {20, "jody"},
     65     {30, "vic"},
     66 };
     67 
     68 void ObjectTest()
     69 {
     70     cout << "
    ----ObjectTest----" << endl;
     71 
     72     DoubleLink<stu> *pdlink = new DoubleLink<stu>();
     73 
     74     pdlink->insert(0, arr_stu[0]);
     75     pdlink->appendLast(arr_stu[1]);
     76     pdlink->insertFirst(arr_stu[2]);
     77 
     78     cout << "isEmpty() = " << pdlink->isEmpty() << endl;
     79 
     80     cout << "size() = " << pdlink->getSize() << endl;
     81 
     82     int sz = pdlink->getSize();
     83     struct stu p;
     84     for(int i = 0; i < sz; i++)
     85     {
     86         p = pdlink->get(i);
     87         cout << "pdlink(" << i << ") = [" << p.id << ", " << p.name << "]" << endl;
     88     }
     89 
     90     delete pdlink;
     91 }
     92 
     93 int main()
     94 {
     95     IntTest();
     96     StringTest();
     97     ObjectTest();
     98 
     99     return 0;
    100 }
    View Code

    两种链表的测试结果相同,都为:

    ----IntTest----
    isEmpty() = 0
    size() = 3
    pdlink(0) = 30
    pdlink(1) = 20
    pdlink(2) = 10
    
    ----StringTest----
    isEmpty() = 0
    size() = 3
    pdlink(0) = thirty
    pdlink(1) = ten
    pdlink(2) = twenty
    
    ----ObjectTest----
    isEmpty() = 0
    size() = 3
    pdlink(0) = [30, vic]
    pdlink(1) = [10, sky]
    pdlink(2) = [20, jody]

    三、单向链表的逆序

    1、循环逆序

    代码如下:

     1 #include <iostream>
     2 #include <string>
     3 #include "DoubleLink.h"
     4 #include "SingleLink.h"
     5 using namespace std;
     6 
     7 int main()
     8 {
     9     cout << "
    ----ReverseTest----" << endl;
    10 
    11     SingleLink<int> *pdlink = new SingleLink<int>();
    12 
    13     pdlink->insert(0, 1);
    14     pdlink->insert(0, 2);
    15     pdlink->insert(0, 3);
    16     pdlink->insert(0, 4);
    17     pdlink->insert(0, 5);
    18 
    19     cout << "
    ----Before reverse----" << endl;
    20     cout << "size() = " << pdlink->getSize() << endl;
    21     int sz = pdlink->getSize();
    22     for(int i = 0; i < sz; i++)
    23     {
    24         cout << "pdlink(" << i << ") = " << pdlink->get(i) << endl;
    25     }
    26 
    27      SNode<int> *current = pdlink->getHeadNode();
    28      SNode<int> *next = NULL, *result = NULL;
    29      while(current != NULL)
    30      {
    31          next = current->next;
    32          current->next = result;
    33          result = current;
    34          current = next;
    35      }
    36      pdlink->setHeadNode(result);
    37 
    38      cout << "
    ----After reverse----" << endl;
    39      for(int i = 0; i < sz; i++)
    40      {
    41          cout << "pdlink(" << i << ") = " << pdlink->get(i) << endl;
    42      }
    43 
    44      delete pdlink;
    45 
    46      return 0;
    47 }
    View Code

    根据上面代码的思路,下图以1——>2——>3——>NULL这个链表为例,用图示来说明逆序的过程:

    2、递归逆序

    代码如下:

     1 #include <iostream>
     2 #include <string>
     3 #include "DoubleLink.h"
     4 #include "SingleLink.h"
     5 using namespace std;
     6 
     7 template<class T>
     8 SNode<T> *ReverseSingleLink(SNode<T> *phead)
     9 {
    10     SNode<T> *newHead;
    11     if(phead->next == NULL) return phead;
    12     newHead = ReverseSingleLink(phead->next);
    13 
    14     phead->next->next = phead;
    15     phead->next = NULL;
    16 
    17     return newHead;
    18 }
    19 
    20 int main()
    21 {
    22     cout << "
    ----ReverseTest----" << endl;
    23 
    24     SingleLink<int> *pdlink = new SingleLink<int>();
    25 
    26     pdlink->insert(0, 1);
    27     pdlink->insert(0, 2);
    28     pdlink->insert(0, 3);
    29     pdlink->insert(0, 4);
    30     pdlink->insert(0, 5);
    31 
    32     cout << "
    ----Before reverse----" << endl;
    33     cout << "size() = " << pdlink->getSize() << endl;
    34     int sz = pdlink->getSize();
    35     for(int i = 0; i < sz; i++)
    36     {
    37         cout << "pdlink(" << i << ") = " << pdlink->get(i) << endl;
    38     }
    39 
    40     pdlink->setHeadNode(ReverseSingleLink(pdlink->getHeadNode()));
    41     cout << "
    ----After reverse----" << endl;
    42     cout << "size() = " << pdlink->getSize() << endl;
    43     for(int i = 0; i < sz; i++)
    44     {
    45         cout << "pdlink(" << i << ") = " << pdlink->get(i) << endl;
    46     }
    47 
    48     delete pdlink;
    49 
    50     return 0;
    51 }
    View Code

    两种逆序算法的结果都为:

    ----ReverseTest----
    
    ----Before reverse----
    size() = 5
    pdlink(0) = 5
    pdlink(1) = 4
    pdlink(2) = 3
    pdlink(3) = 2
    pdlink(4) = 1
    
    ----After reverse----
    size() = 5
    pdlink(0) = 1
    pdlink(1) = 2
    pdlink(2) = 3
    pdlink(3) = 4
    pdlink(4) = 5
  • 相关阅读:
    利用 .NET Framework 命令行工具
    和AI机器人Alice的一段聊天记录
    WINDOWS自启动程序的10大隐身之所
    开放式开发/开源项目TimeDog[C#WindowsApp]
    Microsoft月度中文速递
    新安装的VS2003出现了一个问题不能新建项目!
    实例构造器和类型构造器的一些比较
    C++ 模板里面的typename
    vim 折叠的用法
    Redis3:持久化
  • 原文地址:https://www.cnblogs.com/pursuiting/p/7718072.html
Copyright © 2020-2023  润新知