双向链表的实现

 
/*  单链式存储结构中,只有一个指向后继的指针,从某点出发,只能顺序的访
	访问,如果想访问上一个结点必须从头开始,时间复杂度:访问下一个结点
	为O(1),访问上一个结点为O(n)而双向链表可以克服这个问题
	双向链表的结点存在一个数据域和两个指针域:一个指向前驱一个指向后继 */
#ifndef DOUBLELINKLIST_H
#define DOUBLELINKLIST_H
typedef int ElemType; //链表的数据类型
typedef struct node{  //链表结点
	ElemType data; //链表的数据域
	struct node *next; //链表的指针域,指向后继
	struct node *prev; //链表的指针域,指向前驱
}LinkNode,*LinkList;
void InitList(LinkList *l); //初始化链表
void CreateList(LinkList l); //创建一个双向链表
void InsertList(LinkList l,int i,ElemType e); //在双向链表的第i个位置插入元素
void DeleteList(LinkList l,int i); //删除双向链表的第i个位置的元素
void DestroyList(LinkList l); //销毁双向链表
//bool Find(LinkList l,ElemType e); //在双向链表中查找元素看是否存在
void Print(LinkList l); //输出双向链表
int GetListLength(LinkList l); //获取链表的长度
#endif //DOUBLELINKLIST_H


 

#include "DoubleLinkList.h"
#include <stdio.h>
#include <stdlib.h>
void InitList(LinkList *l) //初始化双向链表
{
	(*l) = (LinkList)malloc(sizeof(LinkNode)); //创建头结点,使l成为指向头结点的指针
	(*l)->next = (*l)->prev = NULL; //初始化头结点的两个指针域为NULL
}
void CreateList(LinkList l) //创建一个双向链表
{
	LinkList order = l;
	printf("请输入双向链表的数据:\n");
	int data;
	while((scanf("%d",&data)) != EOF)
	{
		LinkList temp = (LinkList)malloc(sizeof(LinkNode)); //创建新结点
		if(temp) //如果内存分配成功
		{
			temp->data = data;	 //初始化新结点的数据
			temp->next = order->next; //使新结点的指针域指向当前结点所指向的结点
			if(order == l) //如果temp是第一个结点,则他的指向前驱的指针是NULL
				temp->prev = NULL;
			else			//否则就指向当前的结点
				temp->prev = order; 
			order->next = temp; //当前结点的后继指针域指向新结点
			order = order->next; //指向当前结点的指针指向新结点
		}
	}
}
void InsertList(LinkList l,int i,ElemType e) //在链表的第i个位置插入元素e
{
	if(i < 1 || i > GetListLength(l) + 1) //超出范围返回
		return;
	LinkList temp = l;
	for(int j = 0;j < i - 1;++j) //循环到要插入的位置的前一个位置
		temp = temp->next;
	LinkList tp = (LinkList)malloc(sizeof(LinkNode)); //创建新结点
	if(tp) //如果内存分配成功
	{
		tp->data = e; //初始化新结点的数据
		tp->next = temp->next; //初始化新结点的后继指针域
		temp->next->prev = tp; //使当前结点的后继结点的前驱指针域指向新结点
		temp->next = tp; //当前结点指向的后继指针域指向新结点
		tp->prev = temp; //新结点的后继指针域指向当前结点
	}
}
void DeleteList(LinkList l,int i) //删除链表第i个位置的元素
{
	if(i < 1 || i > GetListLength(l)) //超出范围返回
		return;
	LinkList temp = l;
	for(int j = 0;j < i;++j) //遍历到要删除的位置
		temp = temp->next;
	temp->prev->next = temp->next; //使要删除结点的前驱的后继指针指向要删除的结点的后继结点
	temp->next->prev = temp->prev; //使要删除结点的后继结点的前驱指针指向要删除结点的后继结点
	free(temp); //释放空间
}
int GetListLength(LinkList l) //返回链表的长度
{
	int i = 0;
	LinkList temp = l->next;
	while(temp) //遍历获取长度
	{
		temp = temp->next;
		++i;
	}
	return i;
}
void DestroyList(LinkList l) //销毁链表
{
	LinkList  temp = l->next;
	while(temp) //遍历销毁结点
	{
		LinkList tp = temp;
		temp = temp->next;
		free(tp);
	}
	free(l);
}
void Print(LinkList l) //打印链表
{
	LinkList temp = l->next;
	while(temp)
	{
		printf("%d ",temp->data);
		temp = temp->next;
	}
	printf("\n");
}


 

#include "DoubleLinkList.h"
#include <stdio.h>
int main()
{
	LinkList l;
	InitList(&l);
	CreateList(l);
	Print(l);
	printf("在链表的第2个位置插入元素:5\n");
	InsertList(l,2,5);
	Print(l);
	printf("删除链表的第3个位置的元素:\n");
	DeleteList(l,3);
	Print(l);
	DestroyList(l);
	return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值