C双向链表学习笔记

C双向链表学习笔记

​语言:C语言

编译环境:VC6.0

今天学习了Kenneth A.Reek著的《C和指针》一书,从中学习到了新知识,也发现了新问题,在这里做一下记录

首先先看一下代码:

#include
#include


typedef struct NODE 
{
        struct NODE  *fwd;
	struct NODE  *bwd;
	int val;
}Node;
Node *rootp;
int dll_insert(register Node *rootp,int val)
{
	register Node *this1;   //新节点之前的那个节点
	register Node *next;   //新节点之后的那个节点
	register Node *newnode;//新节点

	for(this1 = rootp;(next = this1->fwd) != NULL;this1 = next) 
	{
		if(next->val == val)     
			return 0;
		if(next->val > val)
			break;
	}
	newnode = (Node *)malloc(sizeof(Node));
	if(newnode == NULL)
		return -1;
	newnode->val = val;


	newnode->fwd = next;
	this1 -> fwd = newnode;

	if(this1 != rootp)
		newnode -> bwd = this1;
	else
		newnode -> bwd = NULL;
	if(next != NULL)
		next -> bwd = newnode;
	else
		rootp -> bwd = newnode;
	return 1;
}

int Link_Head_Init()
{
	rootp = (Node *)malloc(sizeof(Node));
	if(rootp ==	NULL)
	{
		printf("Init sb!\n");
		return -1;
		
	}
		
	rootp->fwd = NULL;
	rootp->bwd = NULL;
	rootp->val = 0;
	printf("Init OK!\n");
	return 1;
}

void main()
{
	Node *this2;
	if(Link_Head_Init() == -1)
		printf("Init OK!\n");
	dll_insert(rootp,1);
	dll_insert(rootp,3);
	dll_insert(rootp,6);
	dll_insert(rootp,8);
	dll_insert(rootp,2);
	dll_insert(rootp,1);
	dll_insert(rootp,4);
	dll_insert(rootp,9);
	dll_insert(rootp,10);
	dll_insert(rootp,7);
	dll_insert(rootp,13);
	dll_insert(rootp,14);
	this2 = rootp;
	while(this2 != NULL)
	{
		
		printf("%d\n",this2->val);
		this2 = this2->fwd;
	}
	while(1);
}

一、出现的问题:

1.根节点需要分配空间,并做初始化;

2.出现please enter the path for DBGHEAP.C这个错误的原因是因为但不调试到库函数时,这个函数没有源代码。可以用F10跳过。

二、双向链表知识:

1.双向链表中最重要的是在这个链表中添加一个节点,首先我们看一下把一个节点插入到链表时,可能出现的4种情况:

a.新值可能必须插入到链表的中间位置

b.新值可能必须插入到链表的起始位置

c.新值可能必须插入到链表的结束位置

d.新值可能必须插入到链表的起始位置,又可能必须插入到链表的结束位置(既原链表为空)

2.建立一个双向链表的步骤:

a.声明一个链表类型

		
typedef struct NODE 
{
        struct NODE  *fwd;
	struct NODE  *bwd;
	int val;
}Node;

 
  

其中fwd是指向当前节点的前一节点指针,bwd是指向当前节点的后一节点指针,val为节点保存的值。

 b.定义根节点,并初始化它:

Node *rootp;
 
  
int Link_Head_Init()
{
	rootp = (Node *)malloc(sizeof(Node));
	if(rootp ==	NULL)
	{
		printf("Init sb!\n");
		return -1;
		
	}
		
	rootp->fwd = NULL;
	rootp->bwd = NULL;
	rootp->val = 0;
	printf("Init OK!\n");
	return 1;
}
上面的程序定义一个根节点rootp,并利用 int Link_Head_Init()函数来将其初始化,在这个函数里,malloc为动态分配内存函数,给rootp分配的空间大小问哦Node的大小,在这里需要注意的是一定要检查是否分配成功。后面三句话为这个根节点初始化内容,由于链表为空,所以将器fwd和bwd初始化为NULL。

c.插入节点函数:

int dll_insert(register Node *rootp,int val)
{
	register Node *this1;   //新节点之前的那个节点
	register Node *next;   //新节点之后的那个节点
	register Node *newnode;//新节点

	for(this1 = rootp;(next = this1->fwd) != NULL;this1 = next) 
	{
		if(next->val == val)     
			return 0;
		if(next->val > val)
			break;
	}
	newnode = (Node *)malloc(sizeof(Node));
	if(newnode == NULL)
		return -1;
	newnode->val = val;


	newnode->fwd = next;
	this1 -> fwd = newnode;

	if(this1 != rootp)
		newnode -> bwd = this1;
	else
		newnode -> bwd = NULL;
	if(next != NULL)
		next -> bwd = newnode;
	else
		rootp -> bwd = newnode;
	return 1;
}
在这个函数里,首先定义了三个节点类型的指针,分别表示为指向 新节点之前的那个节点, 新节点之后的那个节点和 新节点,然后利用for循环遍历整个链表,由于这里采用了升序排列,所以找到比当前值大的那个节点,退出for循环,如果发现了和当前值一样的节点,则不添加新节点。然后利用malloc函数给新节点分配空间,将新节点的fwd指向next节点,将当前节点this1指向新节点。然后开始判断当前节点是不是根节点,如果是,就将新节点的bwd指向当前节点this,否则指向NULL,又判断是不是在链表的末尾添加新节点,如果是则将根节点的bwd指向新节点newnode,否则将下一个节点next的bwd指向newnode。


(未完待续)




你可能感兴趣的:(C语言学习)