码迷,mamicode.com
首页 > 其他好文 > 详细

双向链表

时间:2014-07-09 11:44:17      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:双向链表

引言:


        单链表存在一个问题,当我们想要访问某个结点的前一个结点时,要从头结点开始访问。显然这样的操作是令人烦躁的。为此,双向链表出现,它比单链表多出了一个指针域,指向前一个结点。这样,对于双向链表,就可以方便的从后向前遍历链表了。但多出的问题是对于插入和删除结点的开销要增加一倍。


分析描述:


        双向链表存储结构图为:bubuko.com,布布扣,用结构体表示如下:

typedef	int	ElemType;
typedef struct LNode{
	ElemType	data;
	struct LNode *prior;
	struct LNode *next;
}LNode, *PLNode;

        双向链表的初始化。双向链表的初始化,即分配一个LNode结构体大小的内存,使它的prior指针和next指针都指向结点本身。

PLNode InitDList(void)
{
	PLNode HeadLNode = (PLNode)malloc(sizeof(LNode));
	if(HeadLNode == NULL){
		printf("malloc memory fail.\n");	
		return NULL;
	}

	HeadLNode->prior = HeadLNode->next = HeadLNode;

	return HeadLNode;
}

        双向链表创建链表。向已经初始化的双向链表的头部插入结点元素。

PLNode CreateDList(PLNode PHeadNode)
{
	PLNode TmpLNode = (PLNode)malloc(sizeof(LNode));
	if(TmpLNode == NULL){
		printf("malloc memory fail.\n");	
		return PHeadNode;
	}
	TmpLNode->next = NULL;

	while(scanf("%d", &TmpLNode->data) != 0){
		TmpLNode->next        = PHeadNode->next;
		TmpLNode->prior       = PHeadNode;
		PHeadNode->next       = TmpLNode;
		if(TmpLNode->next != NULL)//此处的判断是针对空链表的操作,如果是空链表,下面的语句就不做。
			TmpLNode->next->prior = TmpLNode;	

		TmpLNode = (PLNode)malloc(sizeof(LNode));
		if(TmpLNode == NULL){
			return PHeadNode;
		}
	}
	free(TmpLNode);

	return PHeadNode;
}

          双向链表的遍历。此处的链表的遍历与前面提到的单链表的遍历没有什么不同。需要注意的地方还是对参数的保护。

void TraverseDList(PLNode PHeadNode)
{
	PLNode TmpLNode = PHeadNode;

	if(PHeadNode == NULL) {
		printf("input element faulse.\n");
		return ;
	}

	while(TmpLNode->next != NULL){
		printf("%d ", TmpLNode->next->data);	
		TmpLNode = TmpLNode->next;
	}
	putchar('\n');
}

         双向链表的长度。跟求单链表长度一样。          

int ListLength(PLNode PHeadNode)
{
	int count = 0;
	while(PHeadNode->next != NULL){
		count++;
		PHeadNode = PHeadNode->next;	
	}

	return count;
}

         双向链表中插入节点元素。给定一个双向链表和插入位置,给定一个结点元素,向给定的链表中插入该结点。

PLNode InsertDList(PLNode PHeadNode, ElemType data, int Index)
{
	int index = 0;
	PLNode TmpLNode = PHeadNode;

	if(PHeadNode == NULL || Index < 0 || Index > ListLength(PHeadNode) + 1){
		printf("input element faulse.\n");	
		return NULL;
	}

	for(index = 1; index < Index; index++){
		TmpLNode = TmpLNode->next;	
	}

	PLNode Tmp = (PLNode)malloc(sizeof(LNode));
	if(Tmp == NULL){
		printf("malloc memory faluse.\n");	
		return PHeadNode;
	}
	Tmp->data = data;

	Tmp->next = TmpLNode->next;
	Tmp->prior = TmpLNode->prior;
	TmpLNode->next = Tmp;
	TmpLNode->prior = Tmp;

	return PHeadNode;
}

          双向链表中删除结点

PLNode DeleteList(PLNode PHeadNode,  int Index)
{
	int index;
	PLNode TmpNode = PHeadNode;

	if(PHeadNode == NULL || Index < 0 || Index > ListLength(PHeadNode)){
		printf("input element faulse.\n");	
		return NULL;
	}
	

	for(index = 0; index < Index; index++){
		TmpNode = TmpNode->next;	
	}
	TmpNode->prior->next = TmpNode->next;
	if(TmpNode->next != NULL)
		TmpNode->next->prior = TmpNode->prior;
	free(TmpNode);

	return PHeadNode;
}

        双向链表中删除结点。

PLNode DeleteList(PLNode PHeadNode,  int Index)
{
	int index;
	PLNode TmpNode = PHeadNode;

	if(PHeadNode == NULL || Index <= 0 || Index > ListLength(PHeadNode)){
		printf("input element faulse.\n");	
		return NULL;
	}
	
	for(index = 0; index < Index; index++){
		TmpNode = TmpNode->next;	
	}

	TmpNode->prior->next = TmpNode->next;
	TmpNode->next->prior = TmpNode->prior;

	free(TmpNode);

	return PHeadNode;
}


双向链表,布布扣,bubuko.com

双向链表

标签:双向链表

原文地址:http://blog.csdn.net/to_be_it_1/article/details/37570681

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!