您的位置:首页 > 理论基础 > 数据结构算法

静下心来写算法(之双向链表)

2012-10-05 00:15 78 查看
     据说Linux内核里广泛应用了一种叫做双向循环链表的东西,听起来很高端的样子,像是是双链表的头尾节点连在一起了,以后用空在研究吧。下面还是练习下今天的双向链表吧,先不循环了。
     双向链表比起单向链表貌似就是多了个前驱指针,使得对数据的操作更加方便了,可以方便的访问父节点而不用从头结点一个一个找了。但是代价还是不小的,每个结点都多出了4字节(32位系统上是这样的,其它平台还不清楚)的内存占用。

双向链表:1)在数据结构里有双向指针
                 2)插入或者删除数据时要注意前后结点指针方向的操作



1)双向表数据结构
typedef struct _DLNODE{
int dat;
struct _DLNODE *prev;
struct _DLNODE *next;
}DLNODE;
2)创建结点
DLNODE *creat_node(int value)
{
DLNODE *node;
node=(DLNODE *)malloc(sizeof(DLNODE));
assert(NULL!=node);
node->dat=value;
node->prev=NULL;
node->next=NULL;
return node;
}
3)在表尾添加节点
void add_node(DLNODE *head,int value)
{
DLNODE *node=NULL;
DLNODE *index=head;
node=(DLNODE *)malloc(sizeof(DLNODE));
assert(NULL!=node);
while(NULL!=index->next){
index=index->next;
}
node->dat=value;
node->prev=index;
node->next=NULL;
index->next=node;
}
4)node节点后插入新的节点
void insert_node(DLNODE *node,int value)
{
if(NULL==node)
return;
DLNODE *new_node=creat_node(value);
if(NULL==node->next){
node->next=new_node;
new_node->prev=node;
new_node->next=NULL;
}else{
new_node->prev=node;
new_node->next=node->next;
node->next->prev=new_node;
node->next=new_node;
}
}
5)查找节点
DLNODE *find_data(DLNODE *head,int value)
{
if(NULL==head)
return NULL;
DLNODE *index=head;
while(index->next!=NULL && index->dat!=value){
index=index->next;
}
if(index->dat=value)
return index;
else
return NULL;

}
6)删除节点,m为中心节点,p为前一节点,n为下一节点
void delete_data(DLNODE *head,int value)
{
DLNODE *p=NULL,*n=NULL,*m=NULL;
m=find_data(head,value);
n=m->next;
p=m->prev;
p->next=n;
n->prev=p;
free(m);
}
7)获取链表长度
int get_length(DLNODE *p)
{
if(NULL==p){
return 0;
}else{
return get_length(p->next)+1;
}
}
8)打印数据
void print_node(DLNODE *p)
{
if(p){
printf("%d\t",p->dat);
print_node(p->next);
}
}

有时候明明感觉代码没有问题,可是就是运行不了,编译器不报错,调试也直接通过,然后整个人就接近崩溃的边缘了


仅仅是因为malloc(sizeof(DLNODE));写成了malloc(sizeof(int));怪不得一些高级语言都没指针了,手动管理内存太危险了。。。
处理链表有一种穿针引线的感觉,跟裁缝一样,把一块块的内存缝在一起,挺好玩的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息