双向链表增删查改
1.头插法
2.尾插法
3.指定位置插入
4.删除节点(按照输入的数据进行删除)
5.查找链表
6.打印链表
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef int listType;
typedef struct listNode {
listType data;
struct listNode *pNext;//后节点
struct listNode *pPre;//前节点
}plistNode, *ListNode;
typedef struct list {
ListNode head;//存放头地址
ListNode tail;//存放尾地址
int size;//节点个数
}List;
List *Init_List() {
List *s = (List *)malloc(sizeof(List));
s->head = NULL;
s->tail = NULL;
s->size = 0;
return s;
}
void list_printf(List *s) {//打印链表
ListNode a = s->head;
if (s->size == 0) {
printf("链表为空\n");
return;
}
else {
while (a) {
printf("%d\t", a->data);
a = a->pNext;
}
printf("\n");
}
}
void Insert_tail(List *s, listType n) {//尾插
ListNode pNewNode;
pNewNode = (ListNode)malloc(sizeof(plistNode));//为新节点申请一个内存空间
pNewNode->data = n;
pNewNode->pNext = pNewNode->pPre = NULL;
if (0 == s->size) {//当前链表无数据
s->head = pNewNode;
s->tail = pNewNode;
printf("插入成功\n");
}
else {
s->tail->pNext = pNewNode;
pNewNode->pPre = s->tail;
s->tail = pNewNode;
printf("插入成功\n");
}
s->size += 1;
}
void Insert_head(List *s, listType n) {//头插
ListNode pNewNode;
pNewNode = (ListNode)malloc(sizeof(plistNode));
pNewNode->data = n;
pNewNode->pPre = pNewNode->pNext = NULL;
if (0 == s->size) {
s->head = pNewNode;
s->tail = pNewNode;
printf("插入成功\n");
}
else {
pNewNode->pNext = s->head;
s->head->pPre = pNewNode;
s->head = pNewNode;
printf("插入成功\n");
}
s->size += 1;
}
void Insert_Loc(List *s, listType n, int position) {//指定位置插入
ListNode pNewNode;
pNewNode = (ListNode)malloc(sizeof(plistNode));
pNewNode->data = n;
if (position > s->size) {
printf("您输入的位置大于当前链表的长度,无法插入");
return;
}
if (1 == position) {
pNewNode->pNext = s->head;
s->head->pPre = pNewNode;
s->head = pNewNode;
printf("插入成功\n");
}
else {
ListNode q = s->head;
for (int i = 1; i < position - 1; ++i);
pNewNode->pNext = q->pNext;
q->pNext->pPre = pNewNode;
q->pNext = pNewNode;
pNewNode->pPre = q;
printf("插入成功\n");
}
s->size += 1;
}
void Del_Node(List *s, listType key) {//删除节点
ListNode p = NULL, q = NULL;
p = q = s->head;
if (s->head->data == key) {
s->head = p->pNext;
p->pNext->pPre = NULL;
free(p);//释放节点
printf("删除成功\n");
}
else {
while (p->pNext) {
q = p->pNext;//头结点在上边已经判断过了,所以从头结点的下一个节点开始
if (q->data == key) {
if (q == s->tail) {//判断是否为尾节点
s->tail = q->pPre;//p
q->pPre->pNext = NULL;
printf("删除成功\n");
free(q);
}
else {
q->pPre->pNext = q->pNext;
q->pNext->pPre = q->pPre;
printf("删除成功\n");
free(q);
}
}
p = p->pNext;
}
}
s->size -= 1;
}
void Modify_Node(List *s, int position, listType key) {//修改节点
ListNode p = NULL, q = NULL;
p = q = s->head;
if (1 == position) {
q->data = key;
printf("修改成功\n");
}
else {
q = p->pNext;//从第二个节点开始
for (int i = 2; position == i; ++i, q = q->pNext);
q->data = key;
printf("修改成功\n");
}
}listType Find_Node(List *s, int position) {//查找
listType x = 0;
ListNode q = NULL;
if (position > s->size) {
printf("您输入的位置大于链表长度,无法查找");
return 0;
}
else {
if (1 == position) {
x = s->head->data;
}
else {
for (int i = 2; position == i; ++i, q = q->pNext);
x = q->data;
}
}
return x;
}
int main() {
List *s = Init_List();
int n = 0, y = 0;
while (1) {
int x = 0;
printf("1.在头部插入节点\n");
printf("2.在尾部插入节点\n");
printf("3.在指定位置插入节点\n");
printf("4.删除节点\n");
printf("5.修改指定位置节点数据\n");
printf("6.查找指定位置节点数据\n");
printf("7.打印链表数据\n");
printf("请选择您需要的功能:");
scanf("%d", &x);
switch (x)
{
case 1:
system("cls");
printf("请输入您要插入的数据:");
scanf("%d", &n);
Insert_head(s, n);
break;
case 2:
system("cls");
printf("请输入您要插入的数据:");
scanf("%d", &n);
Insert_tail(s, n);
break;
case 3:
system("cls");
printf("请输入您要插入的数据,插入的位置:");
scanf("%d%d", &n, &y);
Insert_Loc(s, n, y);
break;
case 4:
system("cls");
printf("请输入您要删除的数据:");
scanf("%d", &n);
Del_Node(s, n);
break;
case 5:
system("cls");
printf("请输入您要修改的数据的位置, 以及修改后的数据:");
scanf("%d%d", &n, &y);
Modify_Node(s, n, y);
break;
case 6:
system("cls");
printf("请输入您要查找数据的位置:");
scanf("%d", &n);
printf("%d\n", Find_Node(s, n));
break;
case 7:
system("cls");
list_printf(s);
break;
default:
break;
}
}
}