• C++ 手动实现单向循环链表(课后作业版)


    单向循环链表,并实现增删查改等功能

    首先定义节点类,类成员包含当前节点的值, 指向下一个节点的指针

    循环链表的尾节点指向头节点

    节点定义:

    1. //node definition
    2. template <typename T>
    3. class Node {
    4. public:
    5. T value;
    6. Node* next;
    7. Node() {}
    8. Node(const T& value) {
    9. this->value = value;
    10. next = nullptr;
    11. }
    12. Node(const T& value, const Node& next) {
    13. this->value = value;
    14. this->next = next;
    15. }
    16. };

    然后是链表类的定义,主要包含了增删查改等功能

    1. //LinkList_cycle definition
    2. template <typename T>
    3. class LinkList_cycle {
    4. public:
    5. Node* headnode;
    6. LinkList_cycle();
    7. LinkList_cycle(const T* arr, int len); //array initial
    8. LinkList_cycle(const LinkList_cycle& link);
    9. ~LinkList_cycle();
    10. LinkList_cycle& push_back(T n);
    11. LinkList_cycle& push_front(T n);
    12. LinkList_cycle& insert(int pos, int n, T* arr);
    13. LinkList_cycle& pop_front();
    14. LinkList_cycle& pop_back();
    15. LinkList_cycle& remove(int pos, int num);
    16. LinkList_cycle& reverse();
    17. T& operator[](int n);
    18. T& at(int n);
    19. LinkList_cycle& replace(int pos, int n, T* arr);
    20. int getLen() {return len;}
    21. void clear() {this->~LinkList_cycle();}
    22. void display();
    23. private:
    24. int len = 0;
    25. Node* getNode(int n);
    26. };

    各个函数解释:

    LinkList_cycle();      默认构造函数

    LinkList_cycle(const T* arr, int len);      一般构造函数

    LinkList_cycle(const LinkList_cycle& link)           拷贝构造函数

    ~LinkList_cycle();     析构函数

    LinkList_cycle& push_back(T n);    在尾部添加一个元素

    LinkList_cycle& push_front(T n);     在头部添加一个元素

    LinkList_cycle& insert(int pos, int n, T* arr);   在pos处插入n个元素

    LinkList_cycle& pop_front();    删除第一个节点

    LinkList_cycle& pop_back();    删除最后一个节点

    LinkList_cycle& remove(int pos, int num);     删除pos开始的num个元素

    LinkList_cycle& reverse();     反转链表

    T& operator[](int n);     重载[ ]运算符,返回第n个节点的值

    T& at(int n);                 与[ ]一样,只不过会检查索引是否越界

    LinkList_cycle& replace(int pos, int n, T* arr);    替换n个节点

    int getLen() {return len;}     返回长度,因为len是private

    void clear() {this->~LinkList_cycle();}    清除链表

    void display();    显示链表所有元素

    Node* getNode(int n);     返回第n个节点的指针,是private函数,在其他函数中经常用到
     

    完整代码:

    1. #include
    2. using namespace std;
    3. //node definition
    4. template <typename T>
    5. class Node {
    6. public:
    7. T value;
    8. Node* next;
    9. Node() {}
    10. Node(const T& value) {
    11. this->value = value;
    12. next = nullptr;
    13. }
    14. Node(const T& value, const Node& next) {
    15. this->value = value;
    16. this->next = next;
    17. }
    18. };
    19. //LinkList_cycle definition
    20. template <typename T>
    21. class LinkList_cycle {
    22. public:
    23. Node* headnode;
    24. LinkList_cycle();
    25. LinkList_cycle(const T* arr, int len); //array initial
    26. LinkList_cycle(const LinkList_cycle& link);
    27. ~LinkList_cycle();
    28. LinkList_cycle& push_back(T n);
    29. LinkList_cycle& push_front(T n);
    30. LinkList_cycle& insert(int pos, int n, T* arr);
    31. LinkList_cycle& pop_front();
    32. LinkList_cycle& pop_back();
    33. LinkList_cycle& remove(int pos, int num);
    34. LinkList_cycle& reverse();
    35. T& operator[](int n);
    36. T& at(int n);
    37. LinkList_cycle& replace(int pos, int n, T* arr);
    38. int getLen() {return len;}
    39. void clear() {this->~LinkList_cycle();}
    40. void display();
    41. private:
    42. int len = 0;
    43. Node* getNode(int n);
    44. };
    45. //default constructor
    46. template <typename T>
    47. LinkList_cycle::LinkList_cycle() {
    48. headnode = nullptr;
    49. len = 0;
    50. }
    51. //normal constructor
    52. template <typename T>
    53. LinkList_cycle::LinkList_cycle(const T* arr, int len) {
    54. Node* temp = nullptr;
    55. Node* node = nullptr;
    56. if ( len < 0 ) {
    57. cout << "[error]: illegal length of LinkList_cycle" << endl;
    58. exit(0);
    59. }
    60. node = new Node(arr[0]);
    61. headnode = node;
    62. temp = node;
    63. for ( int i = 1; i < len; i++ ) {
    64. node = nullptr;
    65. node = new Node (arr[i]);
    66. temp->next = node;
    67. temp = temp->next;
    68. }
    69. temp->next = headnode;;
    70. this->len = len;
    71. }
    72. //copy constructor
    73. template <typename T>
    74. LinkList_cycle::LinkList_cycle(const LinkList_cycle& link) {
    75. this->len = link.getLen();
    76. this->headnode = link.headnode;
    77. }
    78. //deconstructor
    79. template <typename T>
    80. LinkList_cycle::~LinkList_cycle() {
    81. if ( headnode == nullptr || len == 0 ) {
    82. headnode = nullptr;
    83. len = 0;
    84. return;
    85. }
    86. this->len = 0;
    87. Node* temp1 = headnode;
    88. Node* temp2 = headnode; //保存headnode
    89. while ( headnode != nullptr ) {
    90. temp1 = headnode;
    91. headnode = headnode->next;
    92. delete temp1;
    93. if ( headnode == temp2 ) //如果next指向headnode了,说明当前的temp1就是最后一个节点了
    94. break;
    95. temp1 = nullptr;
    96. }
    97. headnode = nullptr;
    98. }
    99. //display all elements in LinkList_cycle
    100. template <typename T>
    101. void LinkList_cycle::display() {
    102. if ( this->len == 0 ) {
    103. cout << "[warning]: can not display empty linkedlist" << endl;
    104. return;
    105. }
    106. Node *node = headnode;
    107. for ( int i = 0; i < len; i++ ) {
    108. cout << node->value << " ";
    109. node = node->next;
    110. }
    111. if ( node != headnode ) {
    112. cout << "[error]: the last node->next do not point to headnode, check again" << endl;
    113. }
    114. node = nullptr;
    115. cout << endl;
    116. }
    117. //add one node at the last position
    118. template <typename T>
    119. LinkList_cycle& LinkList_cycle::push_back(T n) {
    120. Node *node = this->getNode(len-1); //获取指向第len-1个node的指针,即len-2节点的next,所以node就是指向最后节点的指针
    121. if ( node->next == headnode ) { //再加一层保护
    122. Node *temp = new Node(n); //创建新node
    123. node->next = temp; //将最后一个节点的next指向新node
    124. temp->next = headnode; //将新node->next指向headnode
    125. this->len++;
    126. }
    127. return *this;
    128. }
    129. //add one node at the first position
    130. template <typename T>
    131. LinkList_cycle& LinkList_cycle::push_front(T n) {
    132. Node* node_new = new Node(n); //新节点
    133. Node *node_end = this->getNode(len-1); //最后节点
    134. node_new->next = headnode; //新节点的next指向第一个节点
    135. node_end->next = node_new; //最后节点的next指向新节点
    136. headnode = node_new; //再让headnode指向新节点
    137. this->len++;
    138. return *this;
    139. }
    140. //insert elements to LinkList_cycle
    141. template <typename T>
    142. LinkList_cycle& LinkList_cycle::insert(int pos, int n, T* arr) {
    143. if ( pos > len-1 || len < 0 ) {
    144. cout << "[error]: illegal insert position, please check again" << endl;
    145. exit(0);
    146. }
    147. Node* node_N = getNode(len-1); //前半部分
    148. Node* temp = node_N->next; //后半部分
    149. Node* node_new = nullptr; //新增加的
    150. for ( int i = 0; i < n; i++ ) {
    151. node_new = new Node (arr[n-1-i]);
    152. node_new->next = temp;
    153. temp = node_new;
    154. node_new = nullptr;
    155. }
    156. node_N->next = temp;
    157. if ( pos == 0) //唯有再0处插入的时候,需要改变头节点,其实对pos=0,一直push_front也行
    158. headnode = temp;
    159. this->len += n;
    160. return *this;
    161. }
    162. //delete the first element
    163. template <typename T>
    164. LinkList_cycle& LinkList_cycle::pop_front() {
    165. if ( this->len == 0 ) {
    166. cout << "[error]: LinkList_cycle don't has any element" << endl;
    167. exit(0);
    168. }
    169. Node* temp = headnode; //先复制一份headnode
    170. headnode = headnode->next; //headnode 前进一步
    171. delete temp; //把第一个节点释放掉
    172. this->len--;
    173. temp = getNode(len-1); //获取最后一个节点
    174. temp->next = headnode; //把最后一个节点的next指向新的headnode
    175. return *this;
    176. }
    177. //delete the last element
    178. template <typename T>
    179. LinkList_cycle& LinkList_cycle::pop_back() {
    180. if ( this->len == 0 ) {
    181. cout << "[error]: LinkList_cycle don't has any element" << endl;
    182. exit(0);
    183. }
    184. Node* temp1 = getNode(len-2);
    185. Node* temp2 = temp1->next;
    186. delete temp2;
    187. temp1->next = headnode;
    188. this->len--;
    189. return *this;
    190. }
    191. //get the last node pointer
    192. template <typename T>
    193. Node* LinkList_cycle::getNode(int n) {
    194. if ( n > len-1 || n < 0) {
    195. cout << "[warning]: index out of range" <
    196. }
    197. n = n%len;
    198. if ( n < 0 )
    199. n = n + len;
    200. Node *node = headnode;
    201. for( int i = 0; i < n; i++ ) {
    202. node = node->next;
    203. }
    204. return node;
    205. }
    206. //remove n elements
    207. template <typename T>
    208. LinkList_cycle& LinkList_cycle::remove(int pos, int num) {
    209. if ( pos > len-1 || len < 0 ) {
    210. cout << "[error]: illegal remove position, please check again" << endl;
    211. exit(0);
    212. } else if ( pos + num > len) {
    213. cout << "[error]: remove index out of range" << endl;
    214. exit(0);
    215. }
    216. Node* node_N = getNode(pos-1);
    217. Node* node_N_num = getNode(pos+num);
    218. Node* temp = getNode(pos);
    219. while ( 1 ) {
    220. Node* node = temp;
    221. temp = temp->next;
    222. if ( temp == node_N_num ) {
    223. break;
    224. }
    225. delete node;
    226. }
    227. if ( pos == 0 ) { //如果从0位置开始删除,要修改头节点
    228. headnode = node_N_num;
    229. node_N->next = headnode;
    230. }
    231. node_N->next = node_N_num;
    232. this->len -= num;
    233. return *this;
    234. }
    235. //reverse LinkList_cycle
    236. template <typename T>
    237. LinkList_cycle& LinkList_cycle::reverse() {
    238. const int num = len;
    239. T arr[num];
    240. Node* temp = headnode;
    241. for ( int i = 0; i < this->len; i++ ) {
    242. arr[i] = temp->value;
    243. temp = temp->next;
    244. }
    245. temp = headnode;
    246. for ( int i = 0; i < this->len; i++ ) {
    247. temp->value = arr[len-i-1];
    248. temp = temp->next;
    249. }
    250. return *this;
    251. }
    252. template <typename T>
    253. T& LinkList_cycle::operator[](int n) {
    254. return this->getNode(n)->value;
    255. }
    256. template <typename T>
    257. LinkList_cycle& LinkList_cycle::replace(int pos, int n, T* arr) {
    258. if ( pos > len-1 || len < 0 ) {
    259. cout << "[error]: illegal remove position, please check again" << endl;
    260. exit(0);
    261. } else if ( pos + n > len) {
    262. cout << "[error]: remove index out of range" << endl;
    263. exit(0);
    264. }
    265. Node* temp = nullptr;
    266. if ( pos == 0 )
    267. temp = headnode;
    268. else
    269. temp = this->getNode(pos);
    270. for ( int i = 0; i < n; i++ ) {
    271. temp->value = arr[i];
    272. temp = temp->next;
    273. }
    274. return *this;
    275. }
    276. int main(){
    277. int arr[]{1,2,4,5,0};
    278. LinkList_cycle<int> link(arr, sizeof(arr)/sizeof(int));
    279. cout << "LinkLint init with arr: " <
    280. link.display();
    281. cout << "push_back:" << endl;
    282. link.push_back(34);
    283. link.display();
    284. cout << "push_front:" << endl;
    285. link.push_front(10);
    286. link.display();
    287. cout << "insert:" << endl;
    288. link.insert(0,4,arr);
    289. link.display();
    290. cout << "pop_front:" << endl;
    291. link.pop_front();
    292. link.display();
    293. cout << "pop_back:" << endl;
    294. link.pop_back();
    295. link.display();
    296. cout << "remove:" << endl;
    297. link.remove(0,3);
    298. link.display();
    299. cout << "[] operator:" << endl;
    300. cout << link[2] << endl;
    301. cout << "replace:" << endl;
    302. int a[] = {6,5,2};
    303. link.replace(0, sizeof(a)/sizeof(int), a);
    304. link.display();
    305. cout << "LinkList_cycle reserve:" << endl;
    306. link.reverse();
    307. link.display();
    308. cout << "clear:" << endl;
    309. link.clear();
    310. cout << "len=" << link.getLen() << endl;
    311. link.display();
    312. }

  • 相关阅读:
    关于差分进化算法(Differential Evolution)
    大三Web课程设计——悬崖上的波妞(4页) HTML+CSS(可以很好的应付老师的作业)
    uni-app开发小程序实用技巧
    秒验丨Android端SDK API使用说明
    规则引擎深度对比,LiteFlow vs Drools!
    Verilog HDL语言要素
    C语言指针详解
    封装你的第一个vue组件
    Mysql编译安装和yum安装
    uniapp中swiper 轮播带左右箭头,点击切换轮播效果demo(整理)
  • 原文地址:https://blog.csdn.net/a1367666195/article/details/128001093