您的位置:首页 > 其它

单链表和双链表 算法与实现

2010-04-14 11:56 253 查看
链表是包含一些数据的独立数据结构(也成为节点)的集合,每个节点都是通过指针链接在一起的。通常节点是动态分配的。事实上,链表中的节点可以存在于内存中的各个地方。,所以在物理上是不是相邻并无影响。
链表在数据结构中占有很大的作用,它可以根据使用情况分配内存,避免内存的浪费。它的插入,删除,查找都是根据指针的访问来实现,删除或添加一个节点不会改变其他数据的位置和内容,和数组相比,链表具有很强的灵活性和可操作性,但是在使用和实现的时候稍微麻烦,而且比较抽象。

单链表
在单链表中,每个节点都包含指向下一个节点的指针,最后一个节点的指针为NULL,以标志最后一个节点。之所以叫单链表也是因为每个节点只存在一个节点指针而已,所以只能顺序访问下一个节点,俗话就是过了这个村就没这个店了。为了记住单链表的第一个位置,可以定义一个头指针head。

单链表的节点创建如下
typedef struct Linear_chain_node

{

int data;

struct Linear_chain_node *link;

} NODE;

创建之后,NODE就是节点的数据类型,它是一个包含一个整形数和一个节点指针的封装数据。

建立单链表的函数算法实现
NODE *Creat_single_chain(int n)

{

NODE *head , *current,*previous;

int i;

previous=(NODE*)malloc(sizeof(NODE));

previous->data = 0;

previous->link = NULL;

head = previous ;

for(i=0;i<n;i++)

{

current = (NODE*)malloc(sizeof(NODE));

scanf("%d",current->data);

current->link = NULL;

previous->link = current;

previous = current;

}

return head;

}

建立单链表中,函数是一个指针函数,指针类型是节点,它最终的返回值是头节点。函数里建立了三个节点指针,分别是头节点指针,当前节点指针和前一个节点指针。先建立头指针,数据为0,指针为NULL。通过传递给该函数的参数n来确定节点的个数。在n个循环内一直建立当前节点,当前节点的数据键盘输入,当前节点指针为空。前一节点的指针指向当前节点,最后把当前指针替换为前一个指针进行下一次循环。

单链表中插入节点算法(在第i个节点之前)
int Insert(NODE *head , int i , int x)

{

NODE *current , *new ;

int j;

if(i<=0)

retuen 0;

current = head;

j = 0;

while((j<i-1) && current != NULL)

{

current = current->link;

j++;

}

if(current = NULL)

return 0;

new = (NODE*)malloc(sizeof(NODE));

new->data = x;

new->link = current->link;

current->link = new;

return 1;

}

函数中,先遍历节点,直到找到需要添加节点的位置,如果遍历到最后一个节点,函数返回,如果跳出遍历循环,说明是插入位置,申请一个新的节点,数据为x,指针指向当前节点指向的后一个节点,当前节点(实际上已经是旧的节点)指向新节点。

单链表中的删除算法
int Delete(NODE *head , int i)

{

NODE *previous , *current ;

int j=1;

if(i<1)

return 0;

previous = head;

while((j<i) && previous->link != NULL)

{

previous = previous->link;

j++;

}

if(previous->link == NULL)

return 0;

current = previous->link;

previous->link = current->link;

free(current);

return 1

}

函数中,先遍历节点,直到找到需要删除节点的位置,将需要删除的节点前一个节点的指针指向其后一个节点,释放内存。

双向链表

顾名思义,双向链表比单链表的多出了一个节点指针,用来指向前一个节点的数据,这样做的好处不言而喻,避免了寻找前面节点时候发生的不方便之举。在数据结构里后面节点称为后继,前面的节点称为前驱。

下面用C描述一下双向链表的建立

实际上,双向链表仅仅加入的前向指针,前向指针指向的是前一个节点,而前一个指针的后向指针也是指向后一个节点,通过这种方式实现了前后访问。单链表理解了之后,双链表理解起来也很简单,原理是差不多的。

双链表的插入算法

int Insert(NODE *head , int x , int y)
{
NODE *current, *new;
current = head->flink;
while((current != head) && (current->data != y))
current=current->flink;
if(current == head)
return 0;

new = (NODE*)malloc(sizeof(NODE));
new->data = x;
new->blink = current;
new->flink = current->flink;
(current->flink)->blink = new;
current->flink->new;
return 1;
}


双链表的删除算法

int Delete(NODE *head,int x)
{
NODE *current;
current = head->flink;
while((current != head) && (current->data != x))
current=current->flink;
if(current == head)
return 0;

(current->blink)->flink = current->flink;
(current->flink)->vlink = current->blink;

free(current);
return 1;
}


typedef struct double_chain_node
{
int data;
struct double_chain_node *blink,*flink;
}NODE;

NODE *Ceate_double_chain(int n)
{
int i;
NODE *head , *previous ,*current;
previous = (NODE*)malloc(sizeof(NODE));
previous->data = 0;
previous->blink = previous->flink = NULL;
head = previous;

for(i=0;i<n;i++)
{
current = (NODE*)malloc(sizeof(NODE));
scanf("%d",¤t->data);
current->flink = NULL;
current->blink = previous;
previous->flink = current;
previous = current;
}
return head;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐