数据结构---线性表之双链表(C语言)

版权声明:本文为博主原创文章,未经博主允许不得转载。 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");
}

---------------------------------------------------------------------------------------------------------------------------------

扫描二维码关注公众号,回复: 3066712 查看本文章
完整代码如下:
#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");
}

 
 

猜你喜欢

转载自blog.csdn.net/lu_LLLR/article/details/79729066