版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lu_LLLR/article/details/79729066
双链表的创建、插入和删除,完整代码在最下方!
---------------------------------------------------------------------------------------------------------------------------------
单链表只能由开始结点走到终端结点,而不能由终端结点走到开始结点。如果要求输出从终端结点到开始结点的数据序列,对于单链表来说就非常麻烦。所以,为解决这个问题,构造了双链表。
双链表:就是在单链表结点上增添了一个指针域,指向当前结点的前驱。
双链表长这个样子:
---------------------------------------------------------------------------------------------------------------------------------
上代码!
(1)双链表结点定义
typedef struct DLNode
{
int data; //data中存放结点数据域
struct DLNode *prior; //指向前驱结点的指针
struct DLNode *next; //指向后继结点的指针
}DLinkList;
(2)将数据放入数组
换了个方法写InData()函数,这种更简洁一些
int n=0;
int a[maxSize] = { 0 };
DLinkList *L;
DLinkList *head;
void InData()
{
int i = 0;
printf("请输入数据:");
while (1)
{
scanf_s("%d", &a[i]);
i++;
n++;
char c = getchar();
if (c == '\n')
break;
}
printf("\n数组中数据为:");
for (int j = 0; j < n; j++)
printf("%d ", a[j]);
return 0;
}
(3)尾插法建立链表
int CreateDList1(DLinkList *L)
{
InData();
DLinkList *s, *r;
L = (DLinkList*)malloc(sizeof(DLinkList));
head = (DLinkList*)malloc(sizeof(DLinkList));
L->prior = NULL;
L->next = NULL; //初始化
r = L; //r始终指向终端结点,开始结点也是尾结点
head = L;
for (int i = 0; i < n; i++)
{
s = (DLinkList*)malloc(sizeof(DLinkList));
s->data = a[i];
r->next = s;
s->prior = r;
r = s;
}
r->next = NULL;
printf("\n尾插法链表数据为:");
for (int j = 0; j < n; j++)
{
head = head->next;
printf("%d ", head->data);
}
}
void main()
{
CreateDList1(&L);
system("pause");
}
结果图如下:
(
4)头插法建立链表
int CreateDList2(DLinkList *L)
{
InData();
DLinkList *s, *r;
L = (DLinkList*)malloc(sizeof(DLinkList));
head = (DLinkList*)malloc(sizeof(DLinkList));
L->prior = NULL;
L->next = NULL; //初始化
head = L;
for (int i = 0; i < n; i++)
{
s = (DLinkList*)malloc(sizeof(DLinkList));
s->data = a[i];
s->next = L->next;
if (L->next != NULL)
{
L->next->prior = s;
}
L->next = s;
s->prior = L;
}
printf("\n头插法链表数据为:");
DLinkList *p = L;
for (int j = 0; j < n; j++)
{
p= p->next;
printf("%d ", p->data);
}
return L;
}
(5)插入结点
int InsertNode()
{
DLinkList *s,*q,*p;
s = (DLinkList*)malloc(sizeof(DLinkList));
q = (DLinkList*)malloc(sizeof(DLinkList));
p = (DLinkList*)malloc(sizeof(DLinkList));
q = head; //此时q指向头结点!这一步很重要
p = head;
int x, e;
printf("\n请输入插入结点的位置:");
scanf_s("%d", &x);
if (x<0 || x>n)
printf("不在区间内!");
printf("\n请输入数据:");
scanf_s("%d", &e);
s->data = e;
for (int i = 0; i < x; i++)
p = p->next;
s->next = p->next;
s->prior = p;
p->next = s;
n++;
printf("插入后链表数据为:");
for (int j = 0; j < n; j++)
{
q = q->next;
printf("%d ", q ->data);
}
return L;
}
(6)删除结点
int DeleteNode()
{
DLinkList *s, *p;
s = (DLinkList*)malloc(sizeof(DLinkList));
p = (DLinkList*)malloc(sizeof(DLinkList));
p = head; //p此时指向头结点
int x;
printf("\n请输入您想删除结点的位置:");
scanf_s("%d", &x);
if (x<0 || x>n)
printf("不在区间内!");
for (int i = 0; i < x; i++)
head = head->next;
s = head->next;
head->next = s->next;
s->next->prior = head;
free(s);
n--;
printf("\n删除结点后链表内数据为:");
for (int j = 0; j < n; j++)
{
p = p->next;
printf("%d ", p->data);
}
return L;
}
void main()
{
//CreateDList1(&L);
CreateDList1(&L);
//InsertNode();
DeleteNode();
system("pause");
}
---------------------------------------------------------------------------------------------------------------------------------
完整代码如下:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#define maxSize 100
typedef struct DLNode
{
int data; //data中存放结点数据域
struct DLNode *prior; //指向前驱结点的指针
struct DLNode *next; //指向后继结点的指针
}DLinkList;
int n=0;
int a[maxSize] = { 0 };
DLinkList *L;
DLinkList *head;
void InData()
{
int i = 0;
printf("请输入数据:");
while (1)
{
scanf_s("%d", &a[i]);
i++;
n++;
char c = getchar();
if (c == '\n')
break;
}
printf("\n数组中数据为:");
for (int j = 0; j < n; j++)
printf("%d ", a[j]);
return 0;
}
/**********************尾插法建立双链表***************/
int CreateDList1(DLinkList *L)
{
InData();
DLinkList *s, *r;
L = (DLinkList*)malloc(sizeof(DLinkList));
head = (DLinkList*)malloc(sizeof(DLinkList));
L->prior = NULL;
L->next = NULL; //初始化
r = L; //r始终指向终端结点,开始结点也是尾结点
head = L;
for (int i = 0; i < n; i++)
{
s = (DLinkList*)malloc(sizeof(DLinkList));
s->data = a[i];
r->next = s;
s->prior = r;
r = s;
}
r->next = NULL;
printf("\n尾插法链表数据为:");
DLinkList *p = L;
for (int j = 0; j < n; j++)
{
p = p->next;
printf("%d ", p->data);
}
return L;
}
/*********************头插法建立双链表*************************/
int CreateDList2(DLinkList *L)
{
InData();
DLinkList *s, *r;
L = (DLinkList*)malloc(sizeof(DLinkList));
head = (DLinkList*)malloc(sizeof(DLinkList));
L->prior = NULL;
L->next = NULL; //初始化
head = L;
for (int i = 0; i < n; i++)
{
s = (DLinkList*)malloc(sizeof(DLinkList));
s->data = a[i];
s->next = L->next;
if (L->next != NULL)
{
L->next->prior = s;
}
L->next = s;
s->prior = L;
}
printf("\n头插法链表数据为:");
DLinkList *p = L;
for (int j = 0; j < n; j++)
{
p= p->next;
printf("%d ", p->data);
}
return L;
}
/*********************************插入结点****************************/
int InsertNode()
{
DLinkList *s,*q,*p;
s = (DLinkList*)malloc(sizeof(DLinkList));
q = (DLinkList*)malloc(sizeof(DLinkList));
p = (DLinkList*)malloc(sizeof(DLinkList));
q = head; //此时q指向头结点!这一步很重要
p = head;
int x, e;
printf("\n请输入插入结点的位置:");
scanf_s("%d", &x);
if (x<0 || x>n)
printf("不在区间内!");
printf("\n请输入数据:");
scanf_s("%d", &e);
s->data = e;
for (int i = 0; i < x; i++)
p = p->next;
s->next = p->next;
s->prior = p;
p->next = s;
n++;
printf("插入后链表数据为:");
for (int j = 0; j < n; j++)
{
q = q->next;
printf("%d ", q ->data);
}
return L;
}
/****************************删除结点************************/
int DeleteNode()
{
DLinkList *s, *p,*q;
s = (DLinkList*)malloc(sizeof(DLinkList));
p = (DLinkList*)malloc(sizeof(DLinkList));
p = head; //p此时指向头结点
q = head;
int x;
printf("\n请输入您想删除结点的位置:");
scanf_s("%d", &x);
if (x<0 || x>n)
printf("不在区间内!");
for (int i = 0; i < x; i++)
q = q->next;
s = q->next;
q->next = s->next;
s->next->prior = q;
free(s);
n--;
printf("\n删除结点后链表内数据为:");
for (int j = 0; j < n; j++)
{
p = p->next;
printf("%d ", p->data);
}
return L;
}
void main()
{
CreateDList1(&L);
//CreateDList2(&L);
InsertNode();
DeleteNode();
system("pause");
}