双链表各种基本运算的算法

 在双链表中,由于每个结点既包括一个指向后继结点的指针有包括一个指向前驱结点的指针,当访问一个结点后既可以依次向后访问又可以依次向前访问。与单链表相比,双链表中访问一个结点的前后结点更便捷。

#include<stdio.h>
#include<malloc.h>
typedef int ElemType;
typedef struct DNode
{
	ElemType data;//存放元素值
	struct DNode *prior;//指向前驱结点
	struct DNode *next;//指向后继结点
}DLinkNode;//双链表的结点类型
void CreateListF(DLinkNode *&L, ElemType a[], int n)//头插法建立双链表
{
	DLinkNode *s;
	L = (DLinkNode*)malloc(sizeof(DLinkNode));
	L->next = NULL;
	for (int i = 0; i < n; i++)
	{
		s = (DLinkNode*)malloc(sizeof(DLinkNode));
		s->data = a[i];
		s->next = L->next;
		if (L->next!= NULL)
			L->next->prior = s;
		L->next = s;
		s->prior = L;
	}
	s = L->next;
	while (s->next != NULL)
		s = s->next;
	s->next = L;
	L->prior = s;
}
void CreateListR(DLinkNode*&L, ElemType a[], int n)//尾插法建立双链表
{
	DLinkNode *s, *r;
	L = (DLinkNode*)malloc(sizeof(DLinkNode));
	L->next = NULL;
	r = L;
	for (int i = 0; i < n; i++)
	{
		s = (DLinkNode*)malloc(sizeof(DLinkNode));
		s->data = a[i];
		r->next = s;
		s->prior = r;
		r = s;
	}
	r->next = L;
	L->prior = r;
}
void InitList(DLinkNode*&L)//初始化线性表
{
	L = (DLinkNode*)malloc(sizeof(DLinkNode));
	L->prior = L->next = L;

}
void DestroyList(DLinkNode *&L)//销毁线性表
{
	DLinkNode *pre = L, *p = pre->next;
	while (p != L)
	{
		free(L);
		pre = p;
		p = pre->next;
	}
	free(pre);
}
bool ListEmpty(DLinkNode *L)//判断线性表是否为空
{
	return(L->next = NULL);
}
int ListLength(DLinkNode *L)//求线性表的长度
{
	DLinkNode *p = L;
	int i = 0;
	while (p->next != L)
	{
		i++;
		p = p->next;
	}
	return i;
}
void DispList(DLinkNode *L)//输出线性表
{
	DLinkNode *p= L->next;
	while (p != L)
	{
		printf("%c", p->data);
		p = p->next;
	}
	printf("\n");
}
bool GetElem(DLinkNode *L, int i, ElemType &e)//求线性表第i个元素值
{
	int j = 1;
	DLinkNode *p = L->next;
	if (i <= 0 || L->next == L)
		return false;
	while (j < i&&p != NULL)
	{
		j++;
		p = p->next;
	}
	if (p == NULL)
		return false;
	else
	{
		e = p->data;
		return true;
	}
}
int LocateElem(DLinkNode *L, ElemType e)//查找第一个值域为e的元素序号
{
	int i = 1;
	DLinkNode *p = L->next;
	while (p != NULL && p->data != e)
	{
		i++;
		p = p->next;
	}
	if (p == NULL)
		return false;
	else
		return i;
}
bool ListInsert(DLinkNode *&L, int i, ElemType e)//插入第i个元素
{
	int j = 0;
	DLinkNode *p = L, *s;
	if (i < 0)
		return false;
	while (j < i - 1 && p != NULL)
	{
		j++;
		p = p->next;
	}
	if (p == NULL)
		return false;
	else
	{
		s = (DLinkNode*)malloc(sizeof(DLinkNode));
		s->data = e;
		s->next = p->next;
		if (p->next != NULL)
			p->next->prior = s;
		s->prior = p;
		p->next = s;
		return true;
	}
}
bool ListDelete(DLinkNode*&L, int i, ElemType &e)//删除第i个元素
{
	int j = 0;
	DLinkNode *p = L, *q;
	if (i <= 0)
		return false;
	while (j < i - 1 && p != NULL)
	{
		j++;
		p = p->next;
	}
	if (p == NULL)
		return false;
	else {
		q = p->next;
		if (q == NULL)
			return false;
		e = q->data;
		p->next = q->next;
		if (p->next != NULL)
			p->next->prior = p;
		free(q);
		return true;
	}
}
int main()
{
	DLinkNode *h;
	ElemType e;
	printf("双链表的基本运算如下:\n");
	printf(" (1) 初始化双链表h\n");
	InitList(h);
	printf(" (2)依次采用尾插法插入a,b,c,d,e元素\n");
	ListInsert(h, 1, 'a');
	ListInsert(h, 2, 'b');
	ListInsert(h, 3, 'c');
	ListInsert(h, 4, 'd');
	ListInsert(h, 5, 'e');
	printf(" (3)输出双链表h:\n");
	DispList(h);
	printf(" (4)双链表h长度:%d\n", ListLength(h));
	printf(" (5)双链表h为%s\n", (ListEmpty(h) ? "空" : "非空"));
	GetElem(h, 3, e);
	printf(" (6)双链表h的第3个元素:%c\n", e);
	printf(" (7)元素a的位置:%d\n", LocateElem(h, 'a'));
	printf(" (8)在第4个元素位置上插入f元素\n");
	ListInsert(h, 4, 'f');
	printf(" (9)输出双链表h:\n");
	DispList(h);
	printf(" (10)删除h的第3个元素\n");
	ListDelete(h, 3, e);
	printf(" (11)输出双链表h:\n");
	DispList(h);
	printf(" (12)释放双链表h\n");
	DestroyList(h);
	return 1;

}

有错请指正!

猜你喜欢

转载自blog.csdn.net/qq_43554997/article/details/88617513