数据结构

// 知识点【浅谈单链表与双链表的区别】:https://blog.csdn.net/kangxidagege/article/details/80211225

链表由节点构成;所以编程的时候得有一个类是Node,还需要一个链表类来维护size等等状态;

请你搞清楚链表和线性表区别,前者不支持随机访问(或者说随机访问效率不如后者);前者erase/remove效率高,后者低。

 我们仅介绍 构造函数、插入、打印、析构、删除 等等基本功能,其他功能都同理。

一、单项链表

1、构造函数初始化链表:

 1 class Node
 2 {
 3 public:
 4     int data_;//数据阈
 5     Node* next_;//指针阈
 6 };
 7 
 8 ......
 9 List()
10     {
11         this->head_ = new Node();12         //this->head_->data_ = 0;//多余?
13         this->head_->next_ = nullptr;
14         this->size_ = 0;
15     };
16 ......

2、插入:看上图绿色箭头,不管插入多少元素,尾部指针必须是NULL,所以插入其实就是将绿色箭头指向的线掐断,然后放入元素,最后链接前驱节点和后(由于是尾部元素,所以没有后驱节点)

 1 //在第pos个元素前一个位置插入
 2 void List::insert(int pos, int value)
 3 {
 4     if (pos < 0 || pos > size_)
 5         return;
 6 
 7     //创建新的节点接受数据
 8     Node* newnode = new Node();
 9     newnode->data_ = value;
11     newnode->next_ = nullptr;
12 
13     //利用辅助指针找到pos前一个节点
14     // 其实这里不断next,无非就是希望p_curr = nullptr
15     // 然后24行 让newnode->next_  = nullptr(这个nullptr是从head_->next 传过来的);也就是尾部插入嘛
16     // 而循环链表 同理 让newnode->next_  = &(head_)(这个 &(head_) 是从head_->next 传过来的);
17     Node* p_curr = head_;
18     for (int i = 0; i < pos; i++) //这个for循环本质上是head_->next_->next_......
19     {
20         p_curr = p_curr->next_;
21     }
22     //现在p_curr就是pos前一个节点的指针阈
23     //新节点入链表
24     newnode->next_ = p_curr->next_;
25     p_curr->next_ = newnode;
26     size_++;
27 }

3、打印:

 1 void List::print()
 2 {
 3     if (size_ == 0)
 4     {
 5         cout << "size = 0" << endl;
 6         return;
 7     }
 8     //遍历
 9     Node* p_curr = head_->next_;
10     while (p_curr != nullptr)
11     {
12         cout << p_curr->data_ << " ";
13         p_curr = p_curr->next_;
14     }
15     cout << endl;
16 }

4、析构:

 1 List::~List()
 2 {
 3     while (size_ != 0)
 4     {
 5         Node* p_curr = head_;
 6         for (int i = 0; i < (size_ - 1); i++)// 012345 i < 5
 7         {
 8             p_curr = p_curr->next_;//for循环执行完,p_curr指向4
 9         }
10         delete p_curr->next_;//删除最后一个元素
11         p_curr->next_ = nullptr;//末尾元素 空指针
12         size_--;
13         print();
14     }
15     delete head_; //这个容易忘记!
16     cout << "delete!" << endl;
17 }

单项链表代码实现:

  1 #include<iostream>
  2 #include<set>
  3 using namespace std;
  4 
  5 class Node
  6 {
  7 public:
  8     int data_;//数据阈
  9     Node* next_;//指针阈
 10 };
 11 
 12 class List
 13 {
 14 public:
 15     List()
 16     {
 17         this->head_ = new Node();// 不分配空间,下面赋值是不合理的!
 18         //this->head_->data_ = 0;//多余?
 19         this->head_->next_ = nullptr;
 20         this->size_ = 0;
 21     };
 22     void insert(int pos, int value);
 23     //重载下表[]
 24     int operator[](int i);
 25     void print();
 26     ~List();
 27     
 28 
 29 public:
 30     Node* head_;
 31     int size_;
 32 };
 33 //在第pos个元素前一个位置插入
 34 void List::insert(int pos, int value)
 35 {
 36     if (pos < 0 || pos > size_)
 37         return;
 38 
 39     //创建新的节点接受数据
 40     Node* newnode = new Node();
 41     newnode->data_ = value;
 42     //cout << "newnode->data_ = " << *newnode->data_ << endl;
 43     newnode->next_ = nullptr;
 44 
 45     //利用辅助指针找到pos前一个节点
 46     // 其实这里不断next,无非就是希望p_curr = nullptr
 47     // 然后56行 让newnode->next_  = nullptr(这个nullptr是从head_->next 传过来的);也就是尾部插入嘛
 48     // 而循环链表 同理 让newnode->next_  = &(head_)(这个 &(head_) 是从head_->next 传过来的);
 49     Node* p_curr = head_;
 50     for (int i = 0; i < pos; i++) //这个for循环本质上是head_->next_->next_......
 51     {
 52         p_curr = p_curr->next_;
 53     }
 54     //现在p_curr就是pos前一个节点的指针阈
 55     //新节点入链表
 56     newnode->next_ = p_curr->next_;//右边
 57     p_curr->next_ = newnode;//左边
 58     size_++;
 59 }
 60 int List::operator[](int i)
 61 {
 62     Node* p_curr = head_;
 63     int count = 0;
 64     while (count <= i)
 65     {
 66         p_curr = p_curr->next_;
 67         count++;
 68     }
 69     return p_curr->data_;
 70 }
 71 void List::print()
 72 {
 73     if (size_ == 0)
 74     {
 75         cout << "size = 0" << endl;
 76         return;
 77     }
 78     //遍历
 79     Node* p_curr = head_->next_;
 80     while (p_curr != nullptr)
 81     {
 82         cout << p_curr->data_ << " ";
 83         p_curr = p_curr->next_;
 84     }
 85     cout << endl;
 86 }
 87 List::~List()
 88 {
 89     while (size_ != 0)
 90     {
 91         Node* p_curr = head_;
 92         for (int i = 0; i < (size_ - 1); i++)// 012345 i < 5
 93         {
 94             p_curr = p_curr->next_;//for循环执行完,p_curr指向4
 95         }
 96         delete p_curr->next_;//删除最后一个元素
 97         p_curr->next_ = nullptr;//末尾元素 空指针
 98         size_--;
 99         print();
100     }
101     delete head_; //这个容易忘记!
102     cout << "delete!" << endl;
103 }
104 
105 int main()
106 {
107     List list1;
108     //<1>插入
109     for (int i = 0; i < 11; i++)
110     {
111         list1.insert(i, i*i);
112     }
113     list1.print();
114     list1.insert(2, 9999);
115     //<2>重载符[]
116     for (int i = list1.size_ - 1; i >= 0; i--)
117     {
118         cout << list1[i] << " ";
119     }
120     cout << endl;
121 
122     List list2;
123     list2.insert(0, 10);
124     list2.insert(1, 20);
125     list2.insert(2, 30);
126     list2.print();
127     int size2 = list2.size_;
128     return 1;
129 }
View Code

二、循环链表

1、构造函数初始化:

 1 class Node
 2 {
 3 public:
 4     int data;
 5     Node* next_;
 6 };
 7 ......
 8 public:
 9     CircleList()
10     {
11         head_ = new Node();
12         //head_->data; 
13         head_->next_ = head_;
14         size_ = 0;
15     }
16 ......

2、插入,同理插入还是将上图绿色箭头断开,放入节点,前驱连接,节点->next指向head_

 1 void CircleList::insert(int pos, int value)
 2 {
 3     Node* newnode = new Node();
 4     newnode->data = value;
 5     newnode->next_ = head_;//其实同上链表
 6     
 7     Node* p_curr = head_;
 8     for (int i = 0; i < pos; i++)
 9     {
10         p_curr = p_curr->next_;
11     }
12 
13     newnode->next_ = p_curr->next_;
14     p_curr->next_ = newnode;
15     size_++;
16 }

3、打印

 1 void CircleList::print()
 2 {
 3     Node* p_curr = head_->next_;
 4     for (int i = 0; i < size_*3; i++)
 5     {
 6         if (p_curr == head_)//关键
 7         {
 8             p_curr = p_curr->next_;
 9         }
10         cout << p_curr->data << " ";
11         p_curr = p_curr->next_;
12     }
13     cout << endl;
14 }

4、析构

 1 ~CircleList() 
 2     {
 3         while (size_ != 0)
 4         {
 5             Node* p_curr = head_;
 6             for (int i = 0; i < (size_ - 1); i++)//012345
 7             {
 8                 p_curr = p_curr->next_;//最终指向4
 9             }
10             delete p_curr->next_;//删除5
11             p_curr->next_ = head_;
12             size_--;
13         }
14         delete head_;
15         cout << "delete!" << endl;
16     }

循环链表代码示例:

  1 // 知识点【浅谈单链表与双链表的区别】:https://blog.csdn.net/kangxidagege/article/details/80211225
  2 #include<iostream>
  3 
  4 using namespace std;
  5 
  6 class Node
  7 {
  8 public:
  9     int data;
 10     Node* next_;
 11 };
 12 
 13 class CircleList
 14 {
 15 public:
 16     CircleList()
 17     {
 18         head_ = new Node();
 19         //head_->data; 
 20         head_->next_ = head_;
 21         size_ = 0;
 22     }
 23     ~CircleList() 
 24     {
 25         while (size_ != 0)
 26         {
 27             Node* p_curr = head_;
 28             for (int i = 0; i < (size_ - 1); i++)//012345
 29             {
 30                 p_curr = p_curr->next_;//最终指向4
 31             }
 32             delete p_curr->next_;//删除5
 33             p_curr->next_ = head_;
 34             size_--;
 35         }
 36         delete head_;
 37         cout << "delete!" << endl;
 38     }
 39     void insert(int pos, int value);
 40     void remove(int pos);
 41     void print();
 42 public:
 43     Node* head_;
 44     int size_;
 45 };
 46 
 47 void CircleList::insert(int pos, int value)
 48 {
 49     Node* newnode = new Node();
 50     newnode->data = value;
 51     newnode->next_ = head_;
 52     
 53     Node* p_curr = head_;
 54     for (int i = 0; i < pos; i++)
 55     {
 56         p_curr = p_curr->next_;
 57     }
 58 
 59     newnode->next_ = p_curr->next_;
 60     p_curr->next_ = newnode;
 61     size_++;
 62 }
 63 
 64 void CircleList::remove(int pos)
 65 {
 66     Node* p_curr = head_;
 67     for (int i = 0; i < pos; i++)
 68     {
 69         p_curr = p_curr->next_;//找到要被删除元素的前一个
 70     }
 71     p_curr->next_ = p_curr->next_->next_;
 72     size_--;
 73 }
 74 
 75 void CircleList::print()
 76 {
 77     Node* p_curr = head_->next_;
 78     for (int i = 0; i < size_*3; i++)
 79     {
 80         if (p_curr == head_)//关键
 81         {
 82             p_curr = p_curr->next_;
 83         }
 84         cout << p_curr->data << " ";
 85         p_curr = p_curr->next_;
 86     }
 87     cout << endl;
 88 }
 89 
 90 int main()
 91 {
 92     CircleList clist;
 93     for (int i = 0; i < 4; i++)
 94     {
 95         clist.insert(i, i + 1);
 96     }
 97     clist.insert(2, 999);
 98     clist.print();
 99     clist.remove(0);
100     clist.print();
101     clist.remove(2);
102     clist.print();
103     clist.remove(1);
104     clist.print();
105     return 1;
106 }
View Code
原文地址:https://www.cnblogs.com/winslam/p/9547278.html