从头再来2—双向链表的增删查
题目要求
使用尾插法进行双向链表的创建
然后查找第二个位置的元素并输出
在第二个位置插入99
在删除第4个位置的元素值
尾插法
循环链表使用尾插法进行插入
①需先将尾指针指向结点的后继指针赋予插入结点的后继指针
②尾指针指向的后继结点不为空时 将尾指针的后继结点的前驱结点指向插入结点
3 尾指针的后继结点指针指向插入节点
④插入节点的前驱指针指向尾指针指向结点
5 再将尾指针指向插入结点
打印链表 从正向输出
如果双向链表为空 则不需要进行打印
依次指向下一结点输出打印 再判断
查找(按位)
注意判断所找位置是否超出链表长度
按位插入
查找要插入位置的前一位结点
如果插入位置前一个结点都为空 不存在 则此处不能在进行插入 断链
将插入位置的之前的结点的后继指针赋予插入节点的后继指针
如果要插入的位置原先存在结点 在改变对应结点的前驱指针
让原位置的结点的前驱指针指向插入结点
插入位置之前的结点的后继指针指向插入结点
插入结点的前驱指针指向插入位置之前的结点
按位删除
查找要删除位置的结点
将要删除结点的后继指针赋值给要删除结点的前驱结点的后继指针
将要删除结点的前驱指针复制给要删除结点的后继结点的前驱指针
代码展示
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType;
//20221223 对双向链表进行操作
//定义双向链表的结构体
typedef struct DLNode {
//双向链表 包含数据域、前驱结点指针和后继结点指针
ElemType data;//数据域
struct DLNode* prior, * next;//前驱结点指针 指向前一个结点 后继结点指向后一个结点
}DLNode,*DLinkList;
//使用尾插法创建双向链表
void insert_rear_create_DLinkList(DLinkList& DL) {
//要对双向链表进行改变所以需要使用引用
DL->prior = NULL;
DL->next = NULL;//对双向链表进行初始化
ElemType x;//存储要插入的元素
DLinkList s, r;//定义一个要插入元素的指针,一个尾指针 指向最后一个元素
r = DL;//链表为空时 头指针和尾指针一起指向头结点
scanf("%d", &x);
while (x != 9999) {
/*循环链表使用尾插法进行插入 ①需先将尾指针指向结点的后继指针赋予插入结点的后继指针
②尾指针指向的后继结点不为空时 将尾指针的后继结点的前驱结点指向插入结点
3 尾指针的后继结点指针指向插入节点
④插入节点的前驱指针指向尾指针指向结点
5 再将尾指针指向插入结点*/
s = (DLinkList)malloc(sizeof(DLNode));//为插入结点申请内存空间
s->data = x;//存入数据
s->next = r->next;//①
if (r->next != NULL) {
r->next->prior = s;//②
}
r->next = s;// 3
s->prior = r;//④
r = s;// 5
scanf("%d", &x);
}
}
// 从头打印双向链表
void print_DLinkList(DLinkList DL) {
//不需要对双向链表的元素进行改变 不需要使用引用
//如果双向链表为空 则不需要进行打印
DL = DL->next;//指向双向链表的第一个元素
while (DL != NULL) {
printf("%3d", DL->data);//打印数据域元素 每个元素占三个位置
DL = DL->next;//指向下一个元素
}
printf("\n");
}
//按位查找双向链表中的元素并返回
DLinkList search_elem_in_DLinkList(DLinkList DL, int i) {
//不需要对链表进行修改不需要使用引用
DL = DL->next;//指向双向链表的第一个结点
int j = 1;
while (j < i) {
if (DL->next != NULL) {
DL = DL->next;//继续指向下一节点
j++;//自增后再进行比较
}
else {
printf("所查找位置超出链表长度\n");
return NULL;//返回空值
}
}
return DL;//返回对应位置的元素
}
//按位插入指定元素
void insert_search_elem_in_DLinkList(DLinkList& DL, int i, ElemType e) {
DLinkList p=search_elem_in_DLinkList(DL, i-1);//查找要插入位置的前一位结点
if (p == NULL) {
return; //如果插入位置前一个结点都为空 不存在 则此处不能在进行插入 断链
}
DLinkList s = (DLinkList)malloc(sizeof(DLNode));//为插入结点申请内存空间
s->data = e;//将要插入数据存入插入结点中
s->next = p->next;//将插入位置的之前的结点的后继指针赋予插入节点的后继指针
if (p->next != NULL) {
//如果要插入的位置原先存在结点 在改变对应结点的前驱指针
p->next->prior = s;//让原位置的结点的前驱指针指向插入结点
}
p->next = s;//插入位置之前的结点的后继指针指向插入结点
s->prior = p;//插入结点的前驱指针指向插入位置之前的结点
}
//按位删除元素
void delete_search_in_DLinkList(DLinkList& DL, int i, DLinkList& e) {
DLinkList p = search_elem_in_DLinkList(DL, i);//查找要删除位置的结点
e = p;//获取要删除的结点
p->prior->next = p->next;//将要删除结点的后继指针赋值给要删除结点的前驱结点的后继指针
p->next->prior = p->prior;//将要删除结点的前驱指针复制给要删除结点的后继结点的前驱指针
}
int main() {
//20221223 创建双向链表 进行增查删操作
//使用尾插法进行双向链表的创建 然后查找第二个位置的元素并输出 在第二个位置插入99 在删除第4个位置的元素值
DLinkList DL = (DLinkList)malloc(sizeof(DLNode));//为头指针的指向在内存中申请相应的空间
insert_rear_create_DLinkList(DL);//使用尾插法在双向链表中插入数据 3 4 5 6 7 9999(停止标识)
print_DLinkList(DL);//从头打印双向链表 3 4 5 6 7
DLinkList search=search_elem_in_DLinkList(DL, 2);//查找第二个位置的元素并输出
if (search) {
//search不为空 时 会进入
printf("查询双向链表的第2位元素是%d\n", search->data);
}
insert_search_elem_in_DLinkList(DL, 2, 99);//再第双向链表的第二个位置插入元素
printf("再第二个位置插入元素99\n");
print_DLinkList(DL);//再次从头打印双向链表 3 99 4 5 6 7
DLinkList e;//用于接收被删除的元素
delete_search_in_DLinkList(DL, 4, e);
if (e) {
//不为空 进入
printf("删除成功,删除的第四位元素是%d\n", e->data);
}
print_DLinkList(DL);//再次从头打印双向链表 3 99 4 6 7
return 0;
}