/*
双链表(带头结点)
*/
#include <cstdio>
#include <iostream>
#include <cstdlib>
using namespace std;
#define ElemType int
typedef struct DNode {
ElemType data;
struct DNode *prior,*next;
}DNode, * DLinkList;
//初始化
bool InitDLinkList(DLinkList& L) {
L = (DNode*)malloc(sizeof(DNode));
if (L == NULL) return false;
L->prior = NULL;
L->next = NULL;
return true;
}
//双链表建立(尾插法 带头结点)
DLinkList List_TailInsert(DLinkList& L) {
int x;
//L = (LinkList)malloc(sizeof(LNode)); //建立头结点 初始化那里已经做了
DNode* s, * r = L;
scanf_s("%d", &x);
while (x != 999) {
s = (DNode*)malloc(sizeof(DNode));
s->data = x;
s->prior = r;
r->next = s;
r = s;
scanf_s("%d", &x);
}
r->next = NULL;
return L;
}
//双链表建立(头插法 带头结点)
DLinkList List_HeadInsert(DLinkList& L) {
DNode* s;
ElemType x;
//L = (LinkList)malloc(sizeof(LNode));
//L->next = NULL; //建立头结点 与 头结点next指向NULL(必不可少) 在初始化那里已经完成
scanf_s("%d", &x);
while (x != 999) {
s = (DNode*)malloc(sizeof(DNode));
s->data = x;
//顺序:对新插入结点s,后 出入 前 出入
s->next = L->next;
if (L->next != NULL)
L->next->prior = s;
s->prior = L;
L->next = s;
scanf_s("%d", &x);
}
return L;
}
//后插
bool InsertNextDNode(DNode* p, DNode* s) {
if (p == NULL || s == NULL) return false;
//顺序:后 出入 前 出入
s->next = p -> next;
if (p->next != NULL)
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
//前插
bool InsertPriorDNode(DNode* p, DNode* s) {
DNode *q = p->prior;
if (p == NULL || q == NULL || s == NULL) return false;
s->next = q->next;
q->next->prior = s;
s->prior = q;
q->next = s;
return true;
}
//删除
bool DeleteNextDNode(DNode* p) {
if (p == NULL)return false;
DNode* q = p->next;
if (q == NULL) return false;
p->next = q->next;
if (q->next != NULL)
q->next->prior = p;
free(q);
return true;
}
//销毁双链表
void DestoryList(DLinkList& L) {
while (L->next != NULL)
DeleteNextDNode(L); //依次删除头结点的后继结点
free(L); //释放头结点
L = NULL; //头指针指向空
}
//按位查找(带头结点)
DNode* GetElem(DLinkList L, int i) {
int j = 1; //计数,初始为1
DNode* p = L->next; //初始指向第1个结点(头结点为第0个)
if (i == 0) return L;
if (i < 1) return NULL;
while (p != NULL && j < i) {
p = p->next;
j++;
}
return p;
}
//按值查找(带头结点)
DNode* LocateElem(DLinkList L, ElemType e, int& i) {
DNode* p = L->next;
i = 1;
while (p != NULL && p->data != e) {
p = p->next;
i++;
}
return p;
}
//求表长(带头结点)长度中不含头结点,只有头结点长度为0
int length(DLinkList L) {
int len = 0;
DNode* p = L;
while (p->next != NULL) {
p = p->next;
len++;
}
return len;
}
//输出全表
void PrintList(DLinkList L) {
DNode* s = L->next;
while (s != NULL) {
printf("%d ", s->data);
s = s->next;
}
cout << "\n";
}
//逆向输出全表(完全自己编写的)
void PrintListReverse(DLinkList L) {
DNode* s = L;
while (s->next != NULL)
s = s->next;
while (s!= L) {
printf("%d ", s->data);
s = s->prior;
}
cout << "\n";
}
int main() {
DLinkList L1, L2;
InitDLinkList(L1);
InitDLinkList(L2);
cout << "请输入L1的值,空格为界,999结束:\n";
List_TailInsert(L1); //单链表建立-尾插法
cout << "请输入L2的值,空格为界,999结束:\n";
List_HeadInsert(L2); //单链表建立-头插法
cout << "L1(尾插法):\n";
PrintList(L1);
PrintListReverse(L1);
cout << "L2(头插法):\n";
PrintList(L2);
PrintListReverse(L2);
DNode* s1, * s2; //注意这里*要每个变量单独加
s1 = GetElem(L1, 6); //按位查找
s2 = GetElem(L2, 9);
cout << "L1按位查找6结果:\n";
printf("%d\n", s1->data);
cout << "L2按位查找9结果:\n";
printf("%d\n", s2->data);
int i1 = 0, i2 = 0;
s1 = LocateElem(L1, 6, i1);
s2 = LocateElem(L2, 9, i2);
cout << "L1按值查找6结果/位序:\n";
printf("%d %d\n", s1->data, i1);
cout << "L2按值查找9结果/位序:\n";
printf("%d %d\n", s2->data, i2);
DNode* node1 = (DNode*)malloc(sizeof(DNode));
node1->data = 69;
DNode* node2 = (DNode*)malloc(sizeof(DNode));
node2->data = 69;
InsertNextDNode(s1, node1);
InsertPriorDNode(s2, node2);
cout << "指定结点后插操作后L1:\n";
PrintList(L1);
cout << "指定结点前插操作后L2:\n";
PrintList(L2);
int l1, l2;
l1 = length(L1);
l2 = length(L1);
cout << "L1表长:\n";
printf("%d\n", l1);
cout << "L2表长:\n";
printf("%d\n", l2);
return 0;
}
数据结构C++实现——线性表之链表(双链表)
最新推荐文章于 2025-02-05 10:25:33 发布