(C语言)双向链表实现案例(数据结构六)

1.数据类型定义

在代码中为了清楚的表示一些错误和函数运行状态,我们预先定义一些变量来表示这些状态。在head.h头文件中有如下定义:

//定义数据结构中要用到的一些变量和类型
#ifndef HEAD_H
#define HEAD_H

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

#define TRUE  1
#define FALSE 0
#define OK    1
#define ERROR  0
#define INFEASIBLE -1
#define OVERFLOW   -2    //分配内存出错

typedef int  Status;     //函数返回值类型
typedef int  ElemType;   //用户定义的数据类型

#endif

2.双链表数据结构实现

typedef struct LNode{
	ElemType data;
	struct LNode *pre;
	struct LNode *next;
}LNode,*Link;

typedef struct DLink{
	Link head;
	Link tail;
	int  len;
}DLink,*DLinkList;

3.双链表代码实现

DLinkList.h文件如下:

#ifndef DLINKLIST_H
#define DLINKLIST_H
#include "head.h"


typedef struct LNode{
	ElemType data;
	struct LNode *pre;
	struct LNode *next;
}LNode,*Link;

typedef struct DLink{
	Link head;
	Link tail;
	int  len;
}DLink,*DLinkList;


Status MakeNode(Link &p,ElemType e){
	p=(Link)malloc(sizeof(LNode));
	if(!p) return OVERFLOW;
	p->data=e;
	return OK;
}

Status FreeNode(Link &p){
	free(p);
	p=NULL;
	return OK;
}
Status InitList(DLinkList &L){
	Link head=(Link)malloc(sizeof(LNode));
	if(!head) return OVERFLOW;
	Link tail=(Link)malloc(sizeof(LNode));
	if(!tail) return OVERFLOW;
	head->data=-99999;
	tail->data=9999;
	head->next=tail;
	tail->next=head;
	head->pre=tail;
	tail->pre=head;

	L=(DLinkList)malloc(sizeof(DLink));
	if(!L) return OVERFLOW;
	L->head=head;
	L->tail=tail;
	L->len=0;
	return OK;
}
Link getPreLink(DLinkList L,int i){
	Link p=L->head;
	for (int n=1;n<i;n++)
	{
		p=p->next;
	}
	return p;
}
Link getNextLink(DLinkList L,int i){
	Link p=L->head;
	for (int n=0;n<i;n++)
	{
		p=p->next;
	}
	return p;
}
Status DListInsert(DLinkList &L,int i,ElemType e){
	if(i<1 ||i>L->len+1) return ERROR;
	Link p=getPreLink(L,i);
	Link n=getNextLink(L,i);
	Link link;
	MakeNode(link,e);
	p->next=link;
	link->next=n;
	n->pre=link;
	link->pre=p;
	L->len++;
	return OK;
}
Status DLinkDelete(DLinkList &L,int i,ElemType &e){
	if(i<1 ||i>L->len) return ERROR;
	Link p=getPreLink(L,i);
	Link n=getNextLink(L,i+1);
	Link link=p->next;
	p->next=link->next;
	n->pre=link->pre;
	e=link->data;
	FreeNode(link);
	link=NULL;
	return OK;
}
Status printDLinkHead(DLinkList L){
	Link Ln=L->head->next;
	printf("head->");
	while(Ln!=L->tail){
		printf("%d->",Ln->data);
		Ln=Ln->next;
	}
	printf("tail");
	return true;
}
Status printDLinkTail(DLinkList L){
	Link Ln=L->tail->pre;
	printf("tail->");
	while(Ln!=L->head){
		printf("%d->",Ln->data);
		Ln=Ln->pre;
	}
	printf("head");
	return true;
}


#endif

4.双链表测试

#include "DLinkList.h"

void main(){
	DLinkList L;
	InitList(L);
	for(int i=1;i<10;i++)
		DListInsert(L,i,i);

	printf("
从头遍历:");
	printDLinkHead(L);
	printf("
从尾遍历:");
	printDLinkTail(L);

	DListInsert(L,5,55);

	printf("
第5位置插入55后从头遍历:");
	printDLinkHead(L);
	printf("
第5位置插入55后从尾遍历:");
	printDLinkTail(L);

	ElemType e;
	DLinkDelete(L,6,e);
	printf("
删除第6位置后从头遍历:");
	printDLinkHead(L);
	printf("
删除第6位置后从尾遍历:");
	printDLinkTail(L);
}



5.测试结果 

从头遍历:head->1->2->3->4->5->6->7->8->9->tail
从尾遍历:tail->9->8->7->6->5->4->3->2->1->head
第5位置插入55后从头遍历:head->1->2->3->4->55->5->6->7->8->9->tail
第5位置插入55后从尾遍历:tail->9->8->7->6->5->55->4->3->2->1->head
删除第6位置后从头遍历:head->1->2->3->4->55->6->7->8->9->tail
删除第6位置后从尾遍历:tail->9->8->7->6->55->4->3->2->1->head


原文地址:https://www.cnblogs.com/whzhaochao/p/5023512.html