#define _CRT_SECURE_NO_WARNINGS//必须要放在第一行
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
typedef struct DNode { //双链表结点类型
ElemType data; //数据域
struct DNode* prior; //前驱指针
struct DNode* next; //后继指针
}DNode,*DLinkList;
//双链表头插法(带头)
DLinkList Dlist_head_insert(DLinkList& DL) {
DNode* s;
int x;
DL = (DLinkList)malloc(sizeof(DNode)); //带头结点的链表
DL->next = NULL; //前驱指针和后继指针都填写为NULL
DL->prior = NULL;
scanf("%d", &x); //从标准输入读取数据
while (x != 9999) {
s = (DLinkList)malloc(sizeof(DNode)); //申请一个空间,强制类型转换
s->data = x;
s->next = DL->next;
if (DL->next != NULL) //插入第一个结点时,不需要这一步操作
DL->next->prior = s;
s->prior = DL; //要插入的结点指向头结点
DL->next = s;
scanf("%d", &x); //读取标准输入
}
return DL;
}
//尾插建立双链表
DLinkList Dlist_tail_insert(DLinkList& DL) {
int x;
DL = (DLinkList)malloc(sizeof(DNode)); //带头结点
DNode* s, * r = DL; //r代表尾指针
DL->prior = NULL;
scanf("%d", &x);
while (x != 9999) {
s = (DNode*)malloc(sizeof(DNode));
s->data = x;
r->next = s;
s->prior = r;
r = s; //r指向新的表尾结点
scanf("%d", &x);
}
r->next = NULL; //尾结点的next指针付志伟NULL
return DL;
}
//新节点插入第i个位置 不会改变头部DL所以DLinkList DL不用加&
bool DListFrontInsert(DLinkList DL, int i, ElemType e)
{
DLinkList p = GetElem(DL, i - 1);//找前一个位置的地址;
if (NULL == p)
{
return false;
}
DLinkList s = (DLinkList)malloc(sizeof(DNode));//为新插入的结点申请空间
s->data = e;
s->next = p->next;
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
//删除第i个结点 不会改变头部DL所以DLinkList DL不用加&
bool DListDelete(DLinkList DL,int i) {
DLinkList p = GetElem(DL, i - 1); //查找删除位置的钱去结点
if (p == NULL)
return false;
DLinkList q = p->next; //找到p的后继结点q
if (q == NULL) //删除元素不存在
return false; //p没有后继
p->next = q->next; //断连
if (q->next != NULL) //q结点不是最后一个结点
q->next->prior = p;
free(q); //释放结点空间
return true;
}
//按序号查找节点值
DNode* GetElem(DLinkList DL, int i) {
int j = 1;
DNode* p = DL->next;
if (i == 0)
return DL;
if (i < 1)
return NULL;
while (p && j < i) {
p = p->next;
j++;
}
return p;
}
//在p结点之后插入s结点
bool InsertNextDNode(DNode* p, DNode* s) {
if (p == NULL || s == NULL) //非法参数
return false;
s->next = p->next; //将结点*s插入到结点*p之后
if (p->next != NULL) //如果p结点有后继结点
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
//链表打印
void PrintDList(DLinkList DL)
{
DL = DL->next;
while (DL != NULL)
{
printf("%3d", DL->data);
DL = DL->next;//指向下一个结点
}
printf("\n");
}
int main() {
DLinkList DL;
DLinkList search;
Dlist_head_insert(DL); //头插建立
Dlist_tail_insert(DL); //尾插建立
PrintDList(DL);
if (search != NULL) {
printf("按序号查找成功\n");
printf("%d\n",search->data);
}
DListFrontInsert(DL, 3, 99);
PrintDList(DL);
DListDelete(DL, 2);
PrintDList(DL);
}
双链表的实现
于 2022-04-27 20:12:44 首次发布