链表

  • 双向链表的C++实现
  • 单向链表的成环问题
  • 环中元素个数
  • 环开始的节点位置

双向链表的C++实现

#pragma once
typedef struct Node
{int value;Node* prev;Node* next;
}node;class DoubleLinklist
{private:int size;node* head;node* tail;
public:DoubleLinklist();~DoubleLinklist();//获取链表大小int GetSize();//判断是否为空bool IsEmpty();//尾插法插入元素节点void Insert(node* n);//头插法插入元素节点void HeadInsert(node* n);//指定位置后插入数据void PosInsert(int pos, node* n);//获取指定位置元素,并打印void GetPosElem(int pos);//搜索指定元素并打印位置void SearchElem(int elem);//删除指定元素void DelPosElem(int pos);//打印链表void ShowLinklist();//反转打印链表void ReverseShowLinklist();//清除所有数据void ClearLinklist();
};
#include"doublelinlist.h"
#include<iostream>
using std::cout;
using std::cin;
using std::endl;DoubleLinklist::DoubleLinklist()
{this->size = 0;this->head = new node;this->head->value = NULL;this->head->prev = this->head->next = NULL;this->tail = new node;this->tail->next = this->tail->prev = NULL;this->tail->value = NULL;
}DoubleLinklist::~DoubleLinklist()
{delete[]head;delete[]tail;
}int DoubleLinklist::GetSize()
{cout << "NOW LINKLIST SIZE == ";cout << this->size << endl;return this->size;
}bool DoubleLinklist::IsEmpty()
{if (this->size)return false;elsereturn true;
}void DoubleLinklist::Insert(node* n)
{if (n){node* temp = new node;temp->next = temp->prev = NULL;temp->value = n->value;if (this->IsEmpty()){this->head->next = temp;temp->next = this->tail;this->tail->prev = temp;temp->prev = this->head;}else{node* pnode = this->tail->prev;pnode->next = temp;temp->next = this->tail;this->tail->prev = temp;temp->prev = pnode;}this->size++;}else{cout << "UNDEFINE NODE\n";}}void DoubleLinklist::HeadInsert(node* n)
{if (n){node* temp = new node;temp->next = temp->prev = NULL;temp->value = n->value;if (this->IsEmpty()){this->head->next = temp;temp->next = this->tail;this->tail->prev = temp;temp->prev = this->head;}else{node* pnode = this->head->next;this->head->next = temp;temp->next = pnode;pnode->prev = temp;temp->prev = this->head;}this->size++;}else{cout << "UNDEFINED NODE\n";}
}void DoubleLinklist::PosInsert(int pos, node* n)//注意插入时前后节点的指针赋值顺序
{                                               //一般先将插入节点的前后指针next、prev赋值if (n)                                        //再改变前节点的next指针,后节点的prev指针{node* temp = new node;temp->next = temp->prev = NULL;temp->value = n->value;if (pos > this->size || pos < 0){cout << "NO SUCH POSITION, DEFULT INSERT IT IN THE END\n";this->Insert(n);}else if (pos == this->size)this->Insert(n);else if (pos == 0)this->HeadInsert(n);else{node* pnode;if (pos <= (this->size / 2)){pnode = this->head;for (int i = 0; i < pos; ++i){pnode = pnode->next;}temp->next = pnode->next;temp->prev = pnode;pnode->next->prev = temp;pnode->next = temp;}else{pnode = this->tail;for (int i = 0; i < (this->size - pos + 1); ++i){pnode = pnode->prev;}temp->next = pnode->next;temp->prev = pnode;pnode->next->prev = temp;pnode->next = temp;}}this->size++;}else{cout << "UNDEFINED NODE\n";}
}void DoubleLinklist::GetPosElem(int pos)
{if (pos <= 0 || pos > this->size)cout << "NO SUCH POSITION\n";else{node* pnode;if (pos <= (this->size / 2)){pnode = head;for (int i = 0; i < pos; ++i){pnode = pnode->next;}}else{pnode = tail;for (int i = 0; i < (this->size + 1 - pos); ++i){pnode = pnode->prev;}}cout << "POSITION [" << pos << "] == ";cout << pnode->value << endl;}
}void DoubleLinklist::SearchElem(int elem)
{if (this->IsEmpty())cout << "NO DATA!\n";else{node* temp = this->head;int flags = 0;for (int i = 0; i < this->size; ++i){temp = temp->next;if (temp->value == elem){flags++;cout << "FIND IT, POSITION == ";cout << i+1 << endl;}}if(!flags)cout << "THERE IS NO DATA YOU WANT\n";}
}void DoubleLinklist::DelPosElem(int pos)
{node* temp;if (pos <= 0 || pos > this->size)cout << "POSITION ERROR\n";else if (pos == 1){temp = this->head->next;head->next = temp->next;temp->next->prev = head;delete temp;}else if (pos == this->size){temp = this->tail->prev;tail->prev = temp->prev;temp->prev->next = this->tail;delete temp;}else{temp = this->head;for (int i = 0; i < pos; ++i){temp = temp->next;}temp->next->prev = temp->prev;temp->prev->next = temp->next;delete temp;}this->size--;
}void DoubleLinklist::ShowLinklist()
{if (this->IsEmpty())cout << "LINKLIST NULL\n";else{node* temp = this->head;for (int i = 0; i < this->size; ++i){temp = temp->next;cout << "[" << i + 1 << "] == " << temp->value << endl;}}
}void DoubleLinklist::ReverseShowLinklist()
{if (this->IsEmpty())cout << "LINKLIST NULL\n";else{node* temp = this->tail;for (int i = 0; i < this->size; ++i){temp = temp->prev;cout << "[" << i + 1 << "] == " << temp->value << endl;}}
}void DoubleLinklist::ClearLinklist()
{if (this->IsEmpty())cout << "LINKLIST NULL\n";else{node* temp = this->head->next;for (int i = 0; i < this->size; ++i){temp = temp->next;delete temp->prev;}}
}
#include"doublelinlist.h"
#include<iostream>
using std::cout;
using std::endl;int main()
{DoubleLinklist lk;node n[10];for (int i = 0; i < 10; ++i){n[i].value = 5 + i;n[i].next = n[i].prev = nullptr;}lk.Insert(&n[2]);lk.Insert(&n[4]);lk.Insert(&n[3]);lk.Insert(&n[1]);lk.Insert(&n[8]);lk.Insert(&n[5]);lk.Insert(&n[0]);lk.ShowLinklist();cout << endl;lk.ReverseShowLinklist();cout << "\n";lk.HeadInsert(&n[1]);lk.HeadInsert(&n[9]);lk.ShowLinklist();cout << endl;lk.ReverseShowLinklist();cout << "\n";lk.PosInsert(4, &n[6]);lk.PosInsert(6, &n[7]);lk.ShowLinklist();cout << "\n";lk.DelPosElem(3);lk.DelPosElem(4);lk.ShowLinklist();cout << "\n";lk.SearchElem(2);lk.SearchElem(17);lk.SearchElem(8);lk.ClearLinklist();return 0;
}

测试结果,基本没有错误出现

[1] == 7
[2] == 9
[3] == 8
[4] == 6
[5] == 13
[6] == 10
[7] == 5[1] == 5
[2] == 10
[3] == 13
[4] == 6
[5] == 8
[6] == 9
[7] == 7[1] == 14
[2] == 6
[3] == 7
[4] == 9
[5] == 8
[6] == 6
[7] == 13
[8] == 10
[9] == 5[1] == 5
[2] == 10
[3] == 13
[4] == 6
[5] == 8
[6] == 9
[7] == 7
[8] == 6
[9] == 14[1] == 14
[2] == 6
[3] == 7
[4] == 9
[5] == 11
[6] == 8
[7] == 12
[8] == 6
[9] == 13
[10] == 10
[11] == 5[1] == 14
[2] == 6
[3] == 9
[4] == 8
[5] == 12
[6] == 6
[7] == 13
[8] == 10
[9] == 5THERE IS NO DATA YOU WANT
THERE IS NO DATA YOU WANT
FIND IT, POSITION == 4

单向链表的成环问题


通过数学归纳法简单推断,即可得出使用快慢指针,快指针2格一跳,慢指针1格一跳,快慢指针终会在环里相遇,并且在相遇之时,慢指针还未走满一个环。

//承接上一章中单向链表类,存在一个头节点
bool Linklist::LinklistIsRing()
{if (this->size == 0)return false;node* fast = this->head->next;node* slow = this->head->next;while (fast != NULL && fast->next != NULL){fast = fast->next->next;slow = slow->next;if (fast == slow)return true;}return false;
}

环中元素个数

int Linklist::RingCount()
{if (this->size == 0)return -1;node* fast = this->head->next;node* slow = this->head->next;int count = 0;while (fast != NULL && fast->next != NULL){fast = fast->next->next;slow = slow->next;if (fast == slow)break;}if (fast == NULL)//追加判断不为环的情况下直接退出return -1;do{slow = slow->next;count++;} while (slow == fast);return count;
}

环开始的节点位置

node* Linklist::GetRingStart()
{if (this->size == 0)return NULL;node* fast = this->head->next;node* slow = this->head->next;int count = 0;while (fast != NULL && fast->next != NULL){fast = fast->next->next;slow = slow->next;if (fast == slow)break;}if (fast == NULL)return NULL;slow = this->head->next;//慢指针回归到头,快指针更改速度为一个,下次相遇即为环的开始节点while (slow != fast){slow = slow->next;fast = fast->next;}return slow;
}

数据结构 链表(二)相关推荐

  1. SDUT _2117 数据结构实验之链表二:逆序建立链表

    点击打开链接 数据结构实验之链表二:逆序建立链表 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem D ...

  2. 数据结构(二)——单链表的头插与尾插

    一.引言 上篇文章我们知道了顺序表的缺点: 插入和删除操作需要移动大量元素. 数组的大小不好确定. 存储分配需要一整段连续的存储空间,不够灵活,造成很多碎片(空闲的空间得不到利用). 所以我们就引入了 ...

  3. 数据结构(二)--队列

    数据结构(二)–队列 文章目录 数据结构(二)--队列 介绍 代码实现 数组方式实现 普通队列 环形队列 链式实现 单向队列 介绍 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front) ...

  4. 剑指offer(C++)-JZ76:删除链表中重复的结点(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回 ...

  5. 剑指offer(C++)-JZ35:复杂链表的复制(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指 ...

  6. 剑指offer(C++)-JZ23:链表中环的入口结点(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 给一个长度为n链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null. ...

  7. 剑指offer(C++)-JZ52:两个链表的第一个公共结点(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入两个无环的单向链表,找出它们的第一个公共结点,如果没有公共节点则返回空.(注意因 ...

  8. 剑指offer(C++)-JZ25:合并两个排序的链表(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入两个递增的链表,单个链表的长度为n,合并这两个链表并使新链表中的节点仍然是递增排 ...

  9. 剑指offer(C++)-JZ24:反转链表(数据结构-链表)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 给定一个单链表的头结点pHead,长度为n,反转该链表后,返回新链表的表头. 数据范 ...

最新文章

  1. iOS实现传递不定长的多个参数
  2. ASP.NET 安全认证(一)
  3. 第17讲:aiohttp 异步爬虫实战
  4. js设计一个带开关的时钟_数电题:三个按键一个灯
  5. mysql怎么复制信息_mysql关于复制的一些信息参考
  6. Ubuntu 开发者工具中心 Ubuntu Make
  7. DB2错误码sqlcode对应表
  8. ECommerceCrawlers项目分析(十二)
  9. 【EDA】8 路彩灯控制器设计与实现
  10. MATLAB六自由度机械臂正逆运动
  11. 构建用户画像-标签体系
  12. 互联网人求职向传统行业倾斜;全国有两成开发者月薪超1.7万 | 美通企业日报...
  13. 中标麒麟linux配置网卡,中标麒麟Linux v7系统下设置双网卡bond或team绑定详细过程...
  14. python爬虫Selenium批量关注微博用户
  15. 淮北职业技术学院计算机官网,淮北职业技术学院
  16. crosstab交叉表_数据透视之交叉表 crosstab()
  17. matlab bfs函数,Matlab脚本和函数
  18. Java Semaphore实现高并发场景下的流量控制(附源码) | 实用代码架构
  19. 比心一直显示服务器繁忙,QQ空间里面的相册打不开是为什么,老是说服务器正忙...
  20. MATLAB如何计算函数导数

热门文章

  1. 【django】模板(templates)
  2. 强网杯2019 Copperstudy
  3. Golang经典面试题下
  4. 疯狂打地鼠游戏核心代码(鼠标变锤子)
  5. Android用shareUserID实现多个Activity显示在同一界面
  6. (74)分析 APC 插入过程 —— KeInsertQueueApc , KiInsertQueueApc
  7. 【Web安全】从xxe到phar反序列化
  8. 【Web】让你的web页面滚动更有趣
  9. KVM console 串口连接虚拟机
  10. MySQL知识点复习