C双向链表学习笔记

来源:互联网 发布:国外有类似淘宝吗 编辑:程序博客网 时间:2024/05/29 12:36

C双向链表学习笔记

​语言:C语言

编译环境:VC6.0

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

首先先看一下代码:

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


(未完待续)




原创粉丝点击