網(wǎng)站首頁 編程語言 正文
本文實例為大家分享了C++實現(xiàn)雙向鏈表的具體代碼,供大家參考,具體內(nèi)容如下
雙向鏈表:兩個指針域,一個指向前結(jié)點,一個指向后結(jié)點
list.h
#pragma once
#define OK ?? ??? ?1
#define ERROR ?? ?0
#define TRUE ?? ?1
#define FALSE ?? ?0
typedef int Status;
typedef int ElemType;
typedef struct DNode
{
?? ?struct DNode *prior;?? ??? ?//前結(jié)點指針域
?? ?ElemType data;?? ??? ??? ??? ?//數(shù)據(jù)域
?? ?struct DNode *next;?? ??? ??? ?//后結(jié)點指針域
}DNode, *DLinkList;?? ??? ??? ??? ?//結(jié)點和指向結(jié)點的指針
bool InitDLinkList(DLinkList &L);?? ??? ??? ??? ??? ??? ?//雙鏈表初始化
Status CreatDLinkList(DLinkList &L);?? ??? ??? ??? ??? ?//尾插法創(chuàng)建鏈表,包含初始化功能
bool InsertNextDNode(DNode *p, DNode *s);?? ??? ??? ??? ?//結(jié)點s插入在結(jié)點p之后
Status DeleteNextDNode(DNode *p, ElemType &e);?? ??? ??? ?//刪除結(jié)點p的后繼節(jié)點?? ??? ??? ??? ?
void ListTraverse(const DLinkList L);?? ??? ??? ??? ??? ?//雙鏈表的遍歷
Status ListInsert(DLinkList &L, int i, ElemType e);?? ??? ?//指定位置插入元素
Status ListDelete(DLinkList &L, int i, ElemType &e);?? ?//指定位置刪除元素
DNode* GetElem(DLinkList L, int i);?? ??? ??? ??? ??? ??? ?//查找鏈表指定位置節(jié)點,返回的是結(jié)點
void DestoryList(DLinkList &L);?? ??? ??? ??? ??? ??? ??? ?//銷毀雙鏈表,需要釋放頭結(jié)點
oper_func.cpp
#include <iostream>
#include"list.h"
bool InitDLinkList(DLinkList &L)
{
?? ?//構(gòu)建空的雙鏈表,作為雙鏈表的頭結(jié)點,數(shù)據(jù)域為空
?? ?L = new DNode;
?? ?if (L == NULL)?? ??? ??? ??? ?//內(nèi)存分配失敗
?? ??? ?return FALSE;
?? ?L->prior = NULL;?? ??? ??? ?//頭結(jié)點的前驅(qū)指針始終指向NULL?? ?
?? ?L->next = NULL;?? ??? ??? ??? ?//暫時指向NULL
?? ?return TRUE;
}
Status CreatDLinkList(DLinkList &L)
{
?? ?//利用InsertNextDNode函數(shù)來創(chuàng)建
?? ?using std::cin;
?? ?using std::cout;
?? ?using std::endl;
?? ?if (InitDLinkList(L))
?? ?{
?? ??? ?DNode *s,*r = L;?? ??? ??? ??? ?//s為新建的新結(jié)點,用來存儲數(shù)據(jù),而r為尾指針,始終指向尾部節(jié)點
?? ??? ?int num;
?? ??? ?cout << "輸入你需要創(chuàng)建的雙鏈表的個數(shù):";
?? ??? ?cin >> num;
?? ??? ?for (int i = 1; i <= num; i++)
?? ??? ?{
?? ??? ??? ?s = new DNode;?? ??? ??? ??? ?//創(chuàng)建的新結(jié)點
?? ??? ??? ?cout << "輸入第" << i << "個元素:";
?? ??? ??? ?cin >> s->data;?? ??? ??? ??? ?//輸入數(shù)據(jù)
?? ??? ??? ?s->next = NULL;
?? ??? ??? ?InsertNextDNode(r,s);?? ??? ?//結(jié)點s插在尾部節(jié)點之后
?? ??? ??? ?r = s;?? ??? ??? ??? ??? ??? ?//尾指針指向新的尾結(jié)點
?? ??? ?}
?? ??? ?return OK;
?? ?}
?? ?else
?? ?{
?? ??? ?cout << "內(nèi)存不夠,單鏈表創(chuàng)建失敗!" << endl;
?? ??? ?return ERROR;
?? ?}
}
//結(jié)點s插入在結(jié)點p之后
bool InsertNextDNode(DNode *p, DNode *s)
{
?? ?if (p == NULL || s == NULL)
?? ??? ?return FALSE;?? ??? ??? ?//非法參數(shù)
?? ?s->next = p->next;
?? ?if (p->next != NULL)?? ??? ?//如果p不是最后一個結(jié)點
?? ?{
?? ??? ?p->next->prior = s;
?? ?}
?? ?s->prior = p;
?? ?p->next = s;
?? ?return TRUE;
}
Status DeleteNextDNode(DNode *p, ElemType &e)
{
?? ?if(p == NULL)
?? ??? ?return FALSE;?? ??? ??? ?//非法參數(shù)
?? ?DNode *q = p->next;?? ??? ??? ?//找到p節(jié)點的后繼節(jié)點
?? ?if (q == NULL)?? ??? ??? ??? ?//節(jié)點p沒有后繼節(jié)點
?? ?{
?? ??? ?return ERROR;
?? ?}
?? ?else
?? ?{
?? ??? ?//有后繼節(jié)點,但是p的后繼節(jié)點為空
?? ??? ?p->next = q->next;
?? ??? ?e = q->data;
?? ??? ?if (q->next != NULL)
?? ??? ?{
?? ??? ??? ?q->next->prior = p;
?? ??? ?}
?? ??? ?delete q;
?? ??? ?return OK;
?? ?}
}
void ListTraverse(const DLinkList L)
{
?? ?using std::cout;
?? ?using std::endl;
?? ?int i = 1;
?? ?DNode *p = L->next;?? ??? ??? ??? ??? ?//指向第一個元素
?? ?if (p == NULL)
?? ?{
?? ??? ?cout << "雙鏈表為空,無法輸出元素!" << endl;
?? ??? ?return;
?? ?}
?? ?while (p)
?? ?{
?? ??? ?cout << "第" << i++ << "個元素為:" << p->data << endl;
?? ??? ?p = p->next;
?? ?}
}
Status ListDelete(DLinkList &L, int i, ElemType &e)
{
?? ?if (i < 1)?? ??? ? ?? ??? ?//位置不合理
?? ??? ?return ERROR;
?? ?//尋找第i-1個結(jié)點
?? ?DNode *p = GetElem(L, i - 1);
?? ?//刪除i-1結(jié)點的后面結(jié)點
?? ?return DeleteNextDNode(p,e);
}
DNode* GetElem(DLinkList L, int i)
{
?? ?DNode *p = L;
?? ?int j = 0;?? ??? ??? ??? ?//表示p指向的當(dāng)前結(jié)點的位置,此時為頭結(jié)點
?? ?while (p != NULL && j < i)
?? ?{
?? ??? ?p = p->next;?? ??? ?//指向下一個結(jié)點
?? ??? ?j++;
?? ?}
?? ?return p;
}
void DestoryList(DLinkList &L)
{
?? ?using std::cout;
?? ?using std::endl;
?? ?ElemType temp;
?? ?int i = 1;
?? ?while (L->next != NULL)
?? ?{
?? ??? ?DeleteNextDNode(L,temp);
?? ??? ?cout << "第" << i++ << "個刪除的元素為:" << temp << endl;
?? ?}
?? ?cout << "雙鏈表全部數(shù)據(jù)銷毀成功!" << endl;
?? ?delete L;
?? ?cout << "頭結(jié)點銷毀,整個雙鏈表銷毀成功!" << endl;
?? ?L = NULL;?? ??? ??? ??? ?//頭指針指向NULL
}
Status ListInsert(DLinkList &L, int i, ElemType e)
{
?? ?if (i < 1)
?? ??? ?return FALSE;
?? ?//尋找第i-1個結(jié)點
?? ?DNode *p = GetElem(L, i - 1);
?? ?//直接在i-1結(jié)點的后面插入元素即可
?? ?DNode *s = new DNode;?? ??? ?//新建節(jié)點
?? ?s->data = e;
?? ?s->next = NULL;
?? ?s->prior = NULL;
?? ?return InsertNextDNode(p,s);
}
main.cpp
/* 雙向鏈表:帶頭結(jié)點,且頭結(jié)點的prior指針時鐘指向為NULL
1、雙鏈表的初始化
2、雙鏈表的創(chuàng)建
3、雙鏈表的結(jié)點插入(相當(dāng)于后插操作):(結(jié)點s插入結(jié)點p之后)需要考慮p結(jié)點是不是最后一個結(jié)點
?? ?如果想前插操作,則找到該節(jié)點的i-1節(jié)點,然后實行后插操作也是一樣
4、雙鏈表的結(jié)點刪除(相當(dāng)于后刪操作):(刪除p節(jié)點的后序節(jié)點q)需要考慮p結(jié)點是不是最后一個結(jié)點
?? ?也要考慮q節(jié)點是不是最后一個結(jié)點
5、雙鏈表的刪除:
6、雙鏈表的遍歷:
7、雙鏈表的銷毀:需要回收頭結(jié)點
*/
#include <iostream>
#include"list.h"
void showMenu()
{
?? ?using std::cout;
?? ?using std::cin;
?? ?using std::endl;
?? ?cout << "*********************************************************" << endl;
?? ?cout << "*** 1.指定位置插入元素?? ??? ??? ?2.刪除指定位置元素 ***" << endl;
?? ?cout << "*** 3.遍歷單鏈表?? ??? ??? ?0.銷毀雙鏈表并退出 ***" << endl;
?? ?cout << "*********************************************************" << endl;
}
int main()
{
?? ?using std::cout;
?? ?using std::cin;
?? ?using std::endl;
?? ?int select = 0, flag = -1;?? ??? ??? ?//輸入的選擇
?? ?DLinkList L;?? ??? ??? ??? ?//L表示頭指針,始終指向表頭
?? ?if (CreatDLinkList(L))?? ??? ?//尾插法創(chuàng)建單鏈表
?? ?{
?? ??? ?cout << "雙鏈表創(chuàng)建成功!" << endl;
?? ?}
?? ?else
?? ??? ?cout << "雙鏈表創(chuàng)建失敗!" << endl;
?? ?while (true)
?? ?{
?? ??? ?showMenu();
?? ??? ?cout << "輸入你的選擇:";
?? ??? ?cin >> select;
?? ??? ?switch (select)
?? ??? ?{
?? ??? ?case 1: {?? ??? ?//指定位置插入元素
?? ??? ??? ?int position = 0, elem = 0;
?? ??? ??? ?cout << "輸入插入的位置和元素:";
?? ??? ??? ?cin >> position >> elem;
?? ??? ??? ?if (ListInsert(L, position, elem))
?? ??? ??? ??? ?cout << "指定位置插入元素成功!" << endl;
?? ??? ??? ?else
?? ??? ??? ??? ?cout << "內(nèi)存分配失敗或者插入位置越界,插入失敗!" << endl;
?? ??? ?}
?? ??? ??? ??? ?break;
?? ??? ?case 2: {?? ??? ?//刪除指定位置節(jié)點
?? ??? ??? ?int position = 0, elem = 0;
?? ??? ??? ?cout << "輸入指定位置:";
?? ??? ??? ?cin >> position;
?? ??? ??? ?if (ListDelete(L, position, elem))
?? ??? ??? ?{
?? ??? ??? ??? ?cout << "刪除指定位置元素成功!元素為:" << elem << endl;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?cout << "單鏈表為空或者刪除位置不合理!" << endl;
?? ??? ??? ?}
?? ??? ?}
?? ??? ??? ??? ?break;
?? ??? ?case 3: {
?? ??? ??? ?ListTraverse(L);
?? ??? ?}
?? ??? ??? ??? ?break;
?? ??? ?case 0: {
?? ??? ??? ?DestoryList(L);
?? ??? ??? ?system("pause");
?? ??? ??? ?return 0;
?? ??? ?}
?? ??? ?break;
?? ??? ?}
?? ?}
?? ?return 0;
}
原文鏈接:https://blog.csdn.net/qq_33373460/article/details/124498538
相關(guān)推薦
- 2022-08-12 Qt實現(xiàn)電子時鐘_C 語言
- 2022-04-05 C++繼承和動態(tài)內(nèi)存分配_C 語言
- 2022-08-22 Golang實現(xiàn)快速求冪的方法詳解_Golang
- 2022-11-22 python枚舉類型定義與使用講解_python
- 2022-10-24 centos編譯安裝mariadb的詳細過程_mariadb
- 2022-06-09 Python列表的索引與切片_python
- 2022-08-12 k8s?series初級calico使用介紹_云其它
- 2022-07-20 nginx?添加http_stub_status_module模塊_nginx
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支