基础数据结构--双向链表的实现

以下代码为双向链表的实现,由于双向链表与单向链表差距不大,因此实现时只实现了增加元素和删除元素的操作。

总结一下与单向链表的区别:

主要是在写代码时要考虑一个链表元素的next指针和pre指针两个方向,包括在进行测试时都要把链表正向,逆向都跑一遍才能确定代码正确性。

链表的操作最复杂之处是在链表头与表尾的讨论。

以下代码已经过VS2012 测试

#include <stdio.h>
#include <stdlib.h>

//链表元素结构
typedef struct listEle
{
	int data;
	struct listEle *pre;
	struct listEle *next;
}listEle;

//链表结构
typedef struct list
{
	listEle *head;
	listEle *tail;
	int length;
}list;

//构造一个空链表
list* createList()
{
	list *l = (list*)malloc(sizeof(list));
	l->head = NULL;
	l->tail = NULL;
	l->length = 0;
	return l;
}

//清空链表
int clearList(list *&l)
{
	if(!l) return -1;
	if(!l->head || !l->tail || l->length == 0) return 1;
	listEle *temp = l->head;
	listEle *dropEle = NULL;
	int i = 0;
	for(;i<l->length && temp; ++i)
	{
		dropEle = temp;
		temp = temp->next;
		free(dropEle);
	}
	l->head = NULL;
	l->tail = NULL;
	l->length = 0 ;
	if(i == l->length) return 1;
	return -1;
}

//销毁链表
void destroyList(list *&l)
{
	if(!l) return ;
	clearList(l);
	free(l);
	l = NULL;
}

//打印链表元素(正序,逆序两遍)
void showList(list *l)
{
	if(!l ) 
	{
		printf("list not exist!\n");
		return ;
	}
	if(!l->head || !l->tail || l->length == 0) 
	{
		printf("empty list!\n");
		return ;
	}
	listEle *temp = l->head;
	int i = 0;
	printf("->:\n");
	for(;i<l->length && temp; ++i,temp = temp->next)
	{
		printf("%d ",temp->data);
	}
	printf("\n");
	temp = l->tail;
	i = 0;
	printf("<-:\n");
	for(;i<l->length && temp; ++i,temp = temp->pre)
	{
		printf("%d ",temp->data);
	}
	printf("\n");
}

//插入元素
int insertElem(list *&l, int index, int *e)
{
	if(!l || index <0 || index >l->length || !e) return -1;
	listEle *temp = l->head;
	listEle *newEle = (listEle*)calloc(1,sizeof(listEle));
	newEle -> data = *e;
	int i = 0;
	for(;i<index -1 && temp; ++i, temp= temp->next);
	if(i==index -1)
	{
		if(temp->next)
		{
			newEle->next = temp->next;
			temp->next->pre = newEle;
		}
		else
		{
			newEle->next = NULL;
			l->tail = newEle;
		}
		temp->next = newEle;
		newEle->pre = temp;
		l->length ++;
		return 1;
	}
	else if(index == 0)
	{
		if(!l->head || l->length == 0)
		{
			if( index > 0) return -1;
			newEle ->next = NULL;
			newEle->pre = NULL;
			l->head = newEle;
			l->tail = newEle;
			l->length = 1;
			return 1;
		}
		else
		{
			newEle->next = l->head;
			l->head->pre = newEle;
			newEle->pre = NULL;
			l->head = newEle;
			l->length ++;
			return 1;
		}
	}
	return -1;
}

//删除元素
int deleteElem(list *&l, int index)
{
	if(!l || !l->head || !l->tail || l->length == 0 || index <0 || index >= l->length) return -1;
	listEle *temp = l->head;
	listEle *dropEle = NULL;
	int i = 0;
	for(;i<index -1 && temp; ++i,temp = temp->next);
	if(i == index -1)
	{
		if(temp->next)
		{
			dropEle = temp->next;
			temp ->next = dropEle->next;
			if(dropEle->next)
			{
				dropEle->next->pre = temp;
			}
			else
			{
				l->tail = temp;
			}
			free(dropEle);
			dropEle=NULL;
			l->length --;
		}
		return -1;
	}
	else if(index == 0)
	{
		dropEle = l->head;
		if(l->tail == l->head) l->tail = NULL;
		l->head = dropEle->next;
		free(dropEle);
		dropEle = NULL;
		l->length --;
		return 1;
	}
	return -1;
}

//检测程序
int main()
{
	list *l = createList();
	int e = 1;
	insertElem(l,0,&e);
	insertElem(l,10,&e);
	e = 2; insertElem(l,1,&e);
	e = 987; insertElem(l,0,&e);
	e = 15; insertElem(l,2,&e);
	e = 234; insertElem(l,0,&e);
	showList(l);

	deleteElem(l,2);
	showList(l);
	deleteElem(l,10);
	deleteElem(l,0);
	deleteElem(l,l->length -1);
	showList(l);

	destroyList(l);
	showList(l);

	getchar();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值