双链表

Posted jiangnansytle

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了双链表相关的知识,希望对你有一定的参考价值。

技术图片
 1 #ifndef _LIST_H_
 2 #define _LIST_H_
 3 //虚基类
 4 template<class ElemType>
 5 class List
 6 {
 7 public:
 8     List() {};
 9     virtual ~List() {};
10     virtual void Clear() = 0;//清空数据结构
11     virtual void Insert(const int& i, const ElemType& X) = 0;//插入元素
12     virtual void ReMove(const int& i) = 0;//移除指定位置的元素
13     virtual void Erase(const ElemType& X) = 0;//删除表中所有X元素
14     virtual int Search(const ElemType& X) const = 0;//搜索某个元素
15     virtual void Traverse() const = 0;//遍历数据结构
16     virtual ElemType Visit(const int& i)const = 0;//访问某个元素
17 };
18 #endif // !_LIST_H_
List.h
技术图片
  1 #ifndef __DLINKLIST_H__
  2 #define __DLINKLIST_H__
  3 #include "List.h"
  4 template<class ElemType>
  5 class dLinkList :public List<ElemType>
  6 {
  7 private:
  8     struct Node
  9     {
 10         ElemType data;
 11         Node* pre, * next;
 12         Node():pre(nullptr),next(nullptr){}
 13         ~Node(){}
 14         Node(const ElemType& x, Node* p = nullptr, Node* n = nullptr)
 15         {
 16             data = x;
 17             pre = p;
 18             next = n;
 19         }
 20     };
 21     Node* Head, * Tail;
 22     int CurrentLength;
 23     Node* Move(int i)const;
 24 public:
 25     dLinkList();
 26     ~dLinkList() { Clear(); delete Head; delete Tail; }
 27     virtual void Clear() override;//清空数据结构
 28     virtual void Insert(const int& i, const ElemType& X) override;//插入元素
 29     virtual void ReMove(const int& i) override;//移除指定位置的元素
 30     virtual void Erase(const ElemType& X) override;//删除表中所有X元素
 31     virtual int Search(const ElemType& X) const override;//搜索某个元素
 32     virtual void Traverse() const override;//遍历数据结构
 33     virtual ElemType Visit(const int& i)const override;//访问某个元素
 34     void Inverse();
 35 };
 36 
 37 template<class ElemType>
 38 typename dLinkList<ElemType>::Node* dLinkList<ElemType>::Move(int i) const
 39 {
 40     Node* p = Head;
 41     while (i-- >= 0)
 42         p = p->next;
 43     return p;
 44 }
 45 
 46 template<class ElemType>
 47 dLinkList<ElemType>::dLinkList():CurrentLength(0)
 48 {
 49     Head = new Node;
 50     Head->next = Tail = new Node;
 51     Tail->pre = Head;
 52 }
 53 
 54 template<class ElemType>
 55 void dLinkList<ElemType>::Clear()
 56 {
 57     Node* p = Head->next,*q=nullptr;
 58     Head->next = Tail;
 59     Tail->pre = Head;
 60     while (p != Tail)
 61     {
 62         q = p;
 63         p = p->next;
 64         delete q;
 65     }
 66     CurrentLength = 0;
 67 }
 68 
 69 template<class ElemType>
 70 void dLinkList<ElemType>::Insert(const int& i, const ElemType& X)
 71 {
 72     Node* pos = Move(i);
 73     Node* newNode = new Node(X, pos->pre, pos);
 74     pos->pre->next = newNode;
 75     pos->pre = newNode;
 76     ++CurrentLength;
 77 }
 78 
 79 template<class ElemType>
 80 void dLinkList<ElemType>::ReMove(const int& i)
 81 {
 82     Node* pos = Move(i);
 83     pos->pre->next = pos->next;
 84     pos->next->pre = pos->pre;
 85     delete pos;
 86     --CurrentLength;
 87 }
 88 
 89 template<class ElemType>
 90 void dLinkList<ElemType>::Erase(const ElemType& X)
 91 {
 92     int delNum = 0;
 93     Node* p = Head->next;
 94     while (p != Tail)
 95     {
 96         if (p->data == X)
 97         {
 98 
 99             Node* delp = p;
100             p = p->next;
101             delp->pre->next = delp->next;
102             delp->next->pre = delp->pre;
103             delete delp;
104             ++delNum;
105         }
106         else
107             p = p->next;
108     }
109     CurrentLength -= delNum;
110 }
111 
112 template<class ElemType>
113 int dLinkList<ElemType>::Search(const ElemType& X) const
114 {
115     int i = 0;
116     for (Node* p = Head->next; p != Tail; p = p->next,++i)
117     {
118         if (p->data == X)
119         {
120             return i;
121         }
122     }
123     return -1;
124 }
125 
126 template<class ElemType>
127 void dLinkList<ElemType>::Traverse() const
128 {
129     for (Node* p = Head->next; p!= Tail; p = p->next)
130     {
131         std::cout << p->data<<std::endl;
132     }
133 }
134 
135 template<class ElemType>
136 ElemType dLinkList<ElemType>::Visit(const int& i) const
137 {
138     return Move(i)->data;
139 }
140 
141 template<class ElemType>
142 void dLinkList<ElemType>::Inverse()
143 {
144     if (Head->next == Tail)
145         return;
146     Node* cur = Head->next->next;
147     Node* cur_next = nullptr;
148     Head->next->next = Tail;
149     Tail->pre = Head->next;
150     while (cur != Tail)
151     {
152         cur_next = cur->next;
153         cur->next = Head->next;
154         cur->pre = Head;
155         Head->next = cur;
156         cur = cur_next;
157     }
158 }
159 #endif // !__DLINKLIST_H__
dLinkList.h
技术图片
  1 #include <iostream>
  2 #include <string.h>
  3 #include "dLinkList.h"
  4 void IntTest()
  5 {
  6     std::cout << "
----------------------IntTest----------------------" << std::endl;
  7     dLinkList<int> dList;
  8     for (int i = 0; i < 10; ++i)
  9     {
 10         dList.Insert(i, i + 10);
 11     }
 12     dList.Traverse();
 13     std::cout << "---------ReMove---------" << std::endl;
 14     dList.ReMove(5);
 15     dList.Traverse();
 16     std::cout << "---------Insert---------" << std::endl;
 17     dList.Insert(5,999);
 18     dList.Insert(2, 999);
 19     dList.Insert(0, 999);
 20     dList.Traverse();
 21     std::cout << "---------Erase---------" << std::endl;
 22     dList.Erase(999);
 23     dList.Traverse();
 24     std::cout << "---------Search---------" << std::endl;
 25     std::cout << dList.Search(18) << std::endl;
 26     std::cout << "---------Visit---------" << std::endl;
 27     std::cout << dList.Visit(5) << std::endl;
 28     std::cout << "---------Inverse---------" << std::endl;
 29     dList.Inverse();
 30     dList.Traverse();
 31 }
 32 
 33 void StringTest()
 34 {
 35     std::cout << "
----------------------StringTest----------------------" << std::endl;
 36     std::string sarr[] = { "aaaa", "bbb", "ccc", "ddd","eee", "fff", "ggg", "hhh","iii","jjj" };
 37     dLinkList<std::string> dList;
 38     for (int i = 0; i < 10; ++i)
 39     {
 40         dList.Insert(i, sarr[i]);
 41     }
 42     dList.Traverse();
 43     std::cout << "---------ReMove---------" << std::endl;
 44     dList.ReMove(5);
 45     dList.Traverse();
 46     std::cout << "---------Insert---------" << std::endl;
 47     dList.Insert(5,"www.baidu.com");
 48     dList.Insert(2, "www.baidu.com");
 49     dList.Insert(0, "www.baidu.com");
 50     dList.Traverse();
 51     std::cout << "---------Erase---------" << std::endl;
 52     dList.Erase("www.baidu.com");
 53     dList.Traverse();
 54     std::cout << "---------Search---------" << std::endl;
 55     std::cout << dList.Search("jjj") << std::endl;
 56     std::cout << "---------Visit---------" << std::endl;
 57     std::cout << dList.Visit(8) << std::endl;
 58     std::cout << "---------Inverse---------" << std::endl;
 59     dList.Inverse();
 60     dList.Traverse();
 61 }
 62 
 63 struct MyStruct
 64 {
 65     int id;
 66     char name[20];
 67     void copy(const MyStruct& tmp)
 68     {
 69         id = tmp.id;
 70         for (int i = 0; i < 20; ++i)
 71         {
 72             name[i] = tmp.name[i];
 73         }
 74     }
 75     bool operator ==(const MyStruct& tmp) const
 76     {
 77         if (this->id == tmp.id)
 78         {
 79             for (int i = 0; i < 20; ++i)
 80             {
 81                 if (this->name[i] != tmp.name[i])
 82                     return false;
 83             }
 84         }
 85         else
 86         {
 87             return false;
 88         }
 89         return true;
 90     }
 91     MyStruct& operator =(const MyStruct& right)
 92     {
 93         copy(right);
 94         return *this;
 95     }
 96 
 97     bool operator !=(const MyStruct& right)
 98     {
 99         if (right == *this)
100             return false;
101         return true;
102     }
103 
104     friend std::ostream& operator <<(std::ostream& os, const MyStruct& self)
105     {
106         os << self.id << "  " << self.name;
107         return os;
108     }
109 };
110 static MyStruct Stdudent[10] =
111 {
112     {1,"ge"},
113     {2,"sheng"},
114     {3,"lu"},
115     {4,"ge1"},
116     {5,"sheng1"},
117     {6,"lu1"},
118     {7,"ge2"},
119     {8,"sheng2"},
120     {9,"lu2"},
121     {10,"lu3"},
122 };
123 
124 void ObjectTest()
125 {
126     std::cout << "
----------------------ObjectTest----------------------" << std::endl;
127     dLinkList<MyStruct> dList;
128     for (int i = 0; i < 10; ++i)
129     {
130         dList.Insert(i, Stdudent[i]);
131     }
132     dList.Traverse();
133     std::cout << "---------ReMove---------" << std::endl;
134     dList.ReMove(0);
135     dList.Traverse();
136     std::cout << "---------Insert---------" << std::endl;
137     dList.Insert(0, Stdudent[3]);
138     dList.Insert(6, Stdudent[3]);
139     dList.Insert(3, Stdudent[3]);
140     dList.Traverse();
141     std::cout << "---------Erase---------" << std::endl;
142     dList.Erase(Stdudent[3]);
143     dList.Traverse();
144     std::cout << "---------Search---------" << std::endl;
145     std::cout << dList.Search(Stdudent[5]) << std::endl;
146     std::cout << "---------Visit---------" << std::endl;
147     std::cout << dList.Visit(5) << std::endl;
148     std::cout << "---------Inverse---------" << std::endl;
149     dList.Inverse();
150     dList.Traverse();
151 }
152 
153 int main()
154 {
155     IntTest();
156     StringTest();
157     ObjectTest();
158     return 0;
159 }
main.cpp

 

以上是关于双链表的主要内容,如果未能解决你的问题,请参考以下文章

基础数据结构---双链表go语言的代码实现

双链表代码实现和讲解

(王道408考研数据结构)第二章线性表-第三节2:双链表的定义及其操作(插入和删除)

数据结构-编程实现一个双链表的建立,双链表的打印,双链表的测长

数据结构(双链表)

双链表删除一个节点