- //0、显示菜单
- void menu()
- {
- cout << "菜单:" << endl;
- cout << "1.初始化或重置链表" << endl;
- cout << "2.销毁链表" << endl;
- cout << "3.清空链表" << endl;
- cout << "4.链表长度" << endl;
- cout << "5.指定位置的元素值" << endl;
- cout << "6.链表已存在元素的位序" << endl;
- cout << "7.求输入元素的直接前驱" << endl;
- cout << "8.求输入元素的直接后继" << endl;
- cout << "9.在第i个位置插入一个元素" << endl;
- cout << "10.删除第i个元素" << endl;
- cout << "11.输出有的链表元素" << endl;
- cout << "12.初始化并用头插法(或尾插法)输入元素" << endl;
- cout << "13.实现单链表的逆序存放" << endl;
- cout << "-1.退出程序" << endl;
- }
- // 定义结构体
- typedef struct DNode
- {
- EleType data;
- struct DNode *prior,*next;
- }Dnode,*DLinkList;
-
- // 1、初始化双向链表
- bool Init_linkList(DLinkList& L)
- {
- L = (DNode*) malloc(sizeof(DNode));
- if(L == nullptr)
- return false;
- else
- {
- L->prior = nullptr;
- L->next = nullptr;
- return true;
- }
- }
注:销毁链表时需要循环释放每个结点所占用的空间。
-
- // 2、销毁链表
- void DestroyLink(DNode *L){//为了避免内存泄露,每次创建链表运行完程序应将创建的链表销毁,避免内存泄露
- DNode *temp;
- DNode *pre;
- temp= L->next;
- while(temp != nullptr){
- pre = temp;
- temp = temp->next;
- free(pre);
- }
- free(L);
- }
-
- // 3、清空双链表
- bool ClearDLink(DNode* L)
- {
- DNode *temp;
- DNode *pre;
- temp= L->next;
- while(temp != nullptr){
- pre = temp;
- temp = temp->next;
- free(pre);
- }
- L->next = nullptr;
- L->prior = nullptr;
- if(L->next == nullptr)
- return true;
- else
- return false;
- }
-
- // 4、求双链表长度
- int LengthLink(Dnode*L)
- {
- int cnt = 0;
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- temp = temp->next;
- cnt ++;
- }
- return cnt;
- }
-
- // 5、指定位置元素
- int elem_check(Dnode*L,int address)// 判断这个位置是否合法
- {
- int cnt = LengthLink(L);
- if(address <= 0 || address > cnt) return false;
- return true;
- }
-
- EleType ElemLink(Dnode *L,int address)// 如果这个位置合法,则进行查找
- {
- int cnt = 0;
- EleType flag;
- DNode *temp;
- DNode *pre;
- temp= L->next;
- while(temp != nullptr){
- pre = temp;
- temp = temp->next;
- if(++ cnt == address) flag = pre->data;
- }
- return flag;
- }
-
- // 6.链表已存在元素的位序
-
- bool judge_address(Dnode *L,EleType elem)
- {
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- if(temp->data == elem) return true;
- temp = temp->next;
- }
- return false;
- }
-
- int AddressLink(Dnode *L,EleType elem)
- {
- int address = 0;
- int cnt = 0;
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- cnt ++;
- if(temp->data == elem) address = cnt;
- temp = temp->next;
- }
- return address;
- }
-
- // 7.求输入元素的直接前驱
-
- bool judge_before(Dnode *L,EleType elem)
- {
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- if(temp->data == elem)
- {
- if(temp->prior == L) return false;
- else return true;
- }
- temp = temp->next;
- }
- return false;
- }
-
- EleType BeforeLink(Dnode *L,EleType elem)
- {
- EleType flag;
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- if(temp->data == elem)
- {
- flag = temp->prior->data;
- }
- temp = temp->next;
- }
- return flag;
- }
求前驱是指,输入一个元素值(而不是位置),求该元素在顺序表中的直接前驱元素值。
-
- // 8.求输入元素的直接后继
- bool judge_after(Dnode *L,EleType elem)
- {
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- if(temp->data == elem)
- {
- if(temp->next == nullptr) return false;
- else return true;
- }
- temp = temp->next;
- }
- return false;
- }
-
- EleType AfterLink(Dnode *L,EleType elem)
- {
- EleType flag;
- DNode *temp;
- temp= L->next;
- while(true){
- if(temp->data == elem)
- {
- flag = temp->next->data;
- break;
- }
- temp = temp->next;
- }
- return flag;
- }
求后继是指:输入一个元素值(而不是位置),求该元素在顺序表中的直接后继元素值。
-
- // 9.在第i个位置插入一个元素
-
- void LinkListInit(Dnode* L,int address,EleType elem)
- {
- Dnode* l;
- l = (DNode*) malloc(sizeof(DNode));
- l->data = elem;
- int cnt = 0;
- DNode *temp;
- temp= L->next;
- int len = LengthLink(L);
- if(address == len + 1)
- {
- temp = L;
- while(true)
- {
- if(temp->next == nullptr)
- {
- l->next = nullptr;
- l->prior = temp;
- temp->next = l;
- return;
- }
- temp = temp->next;
- }
- }
- else
- {
- while(temp != nullptr){
- cnt ++;
- if(cnt == address)
- {
- l->next = temp;
- l->prior = temp->prior;
- temp->prior->next = l;
- temp->prior = l;
- return;
- }
- temp = temp->next;
- }
- }
- }
-
- // 10.删除第i个元素
- void drop(Dnode* L,int address)
- {
- int cnt = 0;
- DNode *temp;
- temp= L->next;
- int len = LengthLink(L);
- if(len == address)
- {
- while(true)
- {
- if(temp->next == nullptr)
- {
- temp->prior->next = nullptr;
- free(temp);
- return;
- }
- temp = temp->next;
- }
- }
- while(temp != nullptr){
- cnt ++;
- if(cnt == address)
- {
- temp->prior->next = temp->next;
- temp->next->prior = temp->prior;
- free(temp);
- return;
- }
- temp = temp->next;
- }
- }
-
- // 11.输出有的链表元素
- void show(Dnode* L)
- {
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- cout << temp->data << " ";
- temp = temp->next;
- }
- cout << endl;
- }
-
- // 12.清空并用头插法(或尾插法)输入元素
- void show12(Dnode* L,int sum)
- {
- ClearDLink(L);
- for(int i = 0; i < sum; i ++)
- {
- Dnode* l;
- l = (DNode*) malloc(sizeof(DNode));
- EleType num;
- cin >> num;
- l->data = num;
- l->next = L->next;
- l->prior = L;
- if(L->next != nullptr)
- {
- L->next->prior = l;
- }
- L->next = l;
- }
- show(L);
- }
-
- void show13(Dnode* L)
- {
- queue
q; - DNode *temp;
- DNode *p;
- temp= L->next;
- while(temp != nullptr){
- q.push(temp->data);
- p = temp;
- temp = temp->next;
- free(p);
- }
- L->next = nullptr;
- L->prior = nullptr;
- while(!q.empty())
- {
- EleType s;
- s = q.front();
- q.pop();
- DNode* l;
- l = (Dnode*) malloc(sizeof(DNode));
- l->data = s;
- l->next = L->next;
- l->prior = L;
- if(L->next != nullptr)
- {
- L->next->prior = l;
- }
- L->next = l;
- }
- }
要求:所有的提示语和输出语句不允许出现在自定义的函数中(输出函数除外),只能在main函数中出现提示语。
注意,每个功能模块一定要考虑非法的情况,并作出相应的提示,例如:求前驱,要分别能够测试第一个元素的前驱、其他正常的元素的前驱、输入一个在表中不存在的元素求其前驱,这三种情况应给出相应的提示语和结果值;插入和删除时要考虑插入或删除的位置是否合法等。
- #include
- using namespace std;
- typedef int EleType;
-
- // 定义结构体
- typedef struct DNode
- {
- EleType data;
- struct DNode *prior,*next;
- }Dnode,*DLinkList;
-
- //0、显示菜单
- void menu()
- {
- cout << "菜单:" << endl;
- cout << "1.初始化或重置链表" << endl;
- cout << "2.销毁链表" << endl;
- cout << "3.清空链表" << endl;
- cout << "4.链表长度" << endl;
- cout << "5.指定位置的元素值" << endl;
- cout << "6.链表已存在元素的位序" << endl;
- cout << "7.求输入元素的直接前驱" << endl;
- cout << "8.求输入元素的直接后继" << endl;
- cout << "9.在第i个位置插入一个元素" << endl;
- cout << "10.删除第i个元素" << endl;
- cout << "11.输出有的链表元素" << endl;
- cout << "12.初始化并用头插法(或尾插法)输入元素" << endl;
- cout << "13.实现单链表的逆序存放" << endl;
- cout << "-1.退出程序" << endl;
- }
-
- // 1、初始化双向链表
- bool Init_linkList(DLinkList& L)
- {
- L = (DNode*) malloc(sizeof(DNode));
- if(L == nullptr)
- return false;
- else
- {
- L->prior = nullptr;
- L->next = nullptr;
- return true;
- }
- }
-
- // 2、销毁链表
- void DestroyLink(DNode *L){//为了避免内存泄露,每次创建链表运行完程序应将创建的链表销毁,避免内存泄露
- DNode *temp;
- DNode *pre;
- temp= L->next;
- while(temp != nullptr){
- pre = temp;
- temp = temp->next;
- free(pre);
- }
- free(L);
- }
-
-
- // 3、清空双链表
- bool ClearDLink(DNode* L)
- {
- DNode *temp;
- DNode *pre;
- temp= L->next;
- while(temp != nullptr){
- pre = temp;
- temp = temp->next;
- free(pre);
- }
- L->next = nullptr;
- L->prior = nullptr;
- if(L->next == nullptr)
- return true;
- else
- return false;
- }
-
- // 4、求双链表长度
- int LengthLink(Dnode*L)
- {
- int cnt = 0;
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- temp = temp->next;
- cnt ++;
- }
- return cnt;
- }
-
- // 5、指定位置元素
- int elem_check(Dnode*L,int address)
- {
- int cnt = LengthLink(L);
- if(address <= 0 || address > cnt) return false;
- return true;
- }
- EleType ElemLink(Dnode *L,int address)
- {
- int cnt = 0;
- EleType flag;
- DNode *temp;
- DNode *pre;
- temp= L->next;
- while(temp != nullptr){
- pre = temp;
- temp = temp->next;
- if(++ cnt == address) flag = pre->data;
- }
- return flag;
- }
-
- // 6.链表已存在元素的位序
-
- bool judge_address(Dnode *L,EleType elem)
- {
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- if(temp->data == elem) return true;
- temp = temp->next;
- }
- return false;
- }
-
- int AddressLink(Dnode *L,EleType elem)
- {
- int address = 0;
- int cnt = 0;
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- cnt ++;
- if(temp->data == elem) address = cnt;
- temp = temp->next;
- }
- return address;
- }
-
- // 7.求输入元素的直接前驱
-
- bool judge_before(Dnode *L,EleType elem)
- {
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- if(temp->data == elem)
- {
- if(temp->prior == L) return false;
- else return true;
- }
- temp = temp->next;
- }
- return false;
- }
-
- EleType BeforeLink(Dnode *L,EleType elem)
- {
- EleType flag;
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- if(temp->data == elem)
- {
- flag = temp->prior->data;
- }
- temp = temp->next;
- }
- return flag;
- }
-
- // 8.求输入元素的直接后继
- bool judge_after(Dnode *L,EleType elem)
- {
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- if(temp->data == elem)
- {
- if(temp->next == nullptr) return false;
- else return true;
- }
- temp = temp->next;
- }
- return false;
- }
-
- EleType AfterLink(Dnode *L,EleType elem)
- {
- EleType flag;
- DNode *temp;
- temp= L->next;
- while(true){
- if(temp->data == elem)
- {
- flag = temp->next->data;
- break;
- }
- temp = temp->next;
- }
- return flag;
- }
-
-
- // 9.在第i个位置插入一个元素
-
- void LinkListInit(Dnode* L,int address,EleType elem)
- {
- Dnode* l;
- l = (DNode*) malloc(sizeof(DNode));
- l->data = elem;
- int cnt = 0;
- DNode *temp;
- temp= L->next;
- int len = LengthLink(L);
- if(address == len + 1)
- {
- temp = L;
- while(true)
- {
- if(temp->next == nullptr)
- {
- l->next = nullptr;
- l->prior = temp;
- temp->next = l;
- return;
- }
- temp = temp->next;
- }
- }
- else
- {
- while(temp != nullptr){
- cnt ++;
- if(cnt == address)
- {
- l->next = temp;
- l->prior = temp->prior;
- temp->prior->next = l;
- temp->prior = l;
- return;
- }
- temp = temp->next;
- }
- }
- }
-
- // 10.删除第i个元素
- void drop(Dnode* L,int address)
- {
- int cnt = 0;
- DNode *temp;
- temp= L->next;
- int len = LengthLink(L);
- if(len == address)
- {
- while(true)
- {
- if(temp->next == nullptr)
- {
- temp->prior->next = nullptr;
- free(temp);
- return;
- }
- temp = temp->next;
- }
- }
- while(temp != nullptr){
- cnt ++;
- if(cnt == address)
- {
- temp->prior->next = temp->next;
- temp->next->prior = temp->prior;
- free(temp);
- return;
- }
- temp = temp->next;
- }
- }
-
- // 11.输出有的链表元素
- void show(Dnode* L)
- {
- DNode *temp;
- temp= L->next;
- while(temp != nullptr){
- cout << temp->data << " ";
- temp = temp->next;
- }
- cout << endl;
- }
-
- // 12.初始化并用头插法(或尾插法)输入元素
- void show12(Dnode* L,int sum)
- {
- ClearDLink(L);
- for(int i = 0; i < sum; i ++)
- {
- Dnode* l;
- l = (DNode*) malloc(sizeof(DNode));
- EleType num;
- cin >> num;
- l->data = num;
- l->next = L->next;
- l->prior = L;
- if(L->next != nullptr)
- {
- L->next->prior = l;
- }
- L->next = l;
- }
- show(L);
- }
-
- void show13(Dnode* L)
- {
- queue
q; - DNode *temp;
- DNode *p;
- temp= L->next;
- while(temp != nullptr){
- q.push(temp->data);
- p = temp;
- temp = temp->next;
- free(p);
- }
- L->next = nullptr;
- L->prior = nullptr;
- while(!q.empty())
- {
- EleType s;
- s = q.front();
- q.pop();
- DNode* l;
- l = (Dnode*) malloc(sizeof(DNode));
- l->data = s;
- l->next = L->next;
- l->prior = L;
- if(L->next != nullptr)
- {
- L->next->prior = l;
- }
- L->next = l;
- }
- }
-
-
- int main()
- {
- DLinkList L;
- int op = -1;
- bool flag = false;
- menu();
- while(op != 0)
- {
- cout << "<------------------------------>" << endl << "请输入你的选择:";
- cin >> op;
- if(op == 1)
- {
- // 1.初始化或重置链表
- if(Init_linkList(L))
- {
- cout << "初始化成功!" << endl;
- flag = true;
- }
- else cout << "初始化失败!" << endl;
- }else if(op == 2)
- {
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- // 2.销毁链表
- DestroyLink(L);
- flag = false;
- cout << "成功销毁链表!" << endl;
- }else if(op == 3)
- {
- // 3.清空链表
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- if(ClearDLink(L))
- cout << "清空链表成功!" << endl;
- else
- cout << "清空链表失败!" << endl;
- }else if(op == 4)
- {
- // 4.链表长度
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- int l = LengthLink(L);
- cout << "链表长度为:" << l << endl;
- }else if(op == 5)
- {
- // 5.指定位置的元素值
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- int address;
- cout << "请输入位置:";
- cin >> address;
- if(elem_check(L,address))
- {
- EleType ans = ElemLink(L,address);
- cout << "第" << address << "位置的元素为:" << ans << endl;
- }
- else
- {
- cout << "这个位置没有元素!" << endl;
- }
- }else if(op == 6)
- {
- // 6.链表已存在元素的位序
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- EleType elem;
- cout << "请输入查找的元素:";
- cin >> elem;
- if(judge_address(L,elem))
- {
- int address = AddressLink(L,elem);
- cout << "值" << elem << "的位置在" << address << endl;
- }
- else
- {
- cout << "链表中不存在这个值!" << endl;
- }
- }else if(op == 7)
- {
- // 7.求输入元素的直接前驱
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- EleType elem;
- cout << "请输入查找的元素:";
- cin >> elem;
- if(judge_before(L,elem))
- {
- EleType ans;
- ans = BeforeLink(L,elem);
- cout << "元素" << elem << "的直接前驱为:" << ans << endl;
- }
- else
- {
- cout << "这个值没有直接前驱!" << endl;
- }
- }else if(op == 8)
- {
- // 8.求输入元素的直接后继
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- EleType elem;
- cout << "请输入查找的元素:";
- cin >> elem;
- if(judge_after(L,elem))
- {
- EleType ans;
- ans = AfterLink(L,elem);
- cout << "元素" << elem << "的直接后继为:" << ans << endl;
- }
- else
- {
- cout << "这个值没有直接后继!" << endl;
- }
- }
- else if(op == 9)
- {
- // 9.在第i个位置插入一个元素
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- int len;
- len = LengthLink(L);
- int address;
- cout << "输入插入位置:";
- cin >> address;
- EleType elem;
- cout << "输入插入元素:";
- cin >> elem;
- if(address < 1 || address > len + 1)
- {
- cout << "这个位置不能插入元素" << endl;
- }
- else
- {
- LinkListInit(L,address,elem);
- cout << "插入成功!" << endl;
- }
- }
- else if(op == 10)
- {
- // 10.删除第i个元素
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- int address;
- cout << "请输入元素位置:";
- cin >> address;
- int len = LengthLink(L);
- if(address < 1 || address > len)
- {
- cout << "这个位置不能删除"<< endl;
- continue;
- }
- drop(L,address);
- cout << "删除成功!" << endl;
- }
- else if(op == 11)
- {
- // 11.输出有的链表元素
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- show(L);
- }
- else if(op == 12)
- {
- // 12.初始化并用头插法(或尾插法)输入元素
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- cout << "初始化并用头插法(或尾插法)输入元素" << endl;
- cout << "请输入插入元素个数:";
- int sum;
- cin >> sum;
- show12(L,sum);
- }
- else if(op == 13)
- {
- // 13.实现单链表的逆序存放
- if(!flag)
- {
- cout << "链表已被销毁" << endl;
- continue;
- }
- show13(L);
- }
- else if(op == -1) break;
- }
- cout << "程序结束!" << endl;
- }
-