双向链表区别于单链表,单链表的每个结点只包含一个指向下一个结点的指针,但是双向链表的指针域包含了前驱和后继,即指向前一个结点和下一个结点的指针。其主要意义在于可以在链表的任意结点位置正序或逆序遍历链表,提高访问链表结点的效率,下面我们一起来看一下。
#define TYPE int
先构造双向链表的结构
typedef struct Node
{
TYPE data;//数据域
struct Node *prior;//前驱
struct Node *next;//后继
}Node;
下面我们对双向链表进行一些基本操作的函数编写:
创建结点
//创建结点
Node *create_node(TYPE data)
{
Node *node=malloc(sizeof(Node));
node->data=data;
node->prior=NULL;
node->next=NULL;
return node;
}
头添加
//头添加
bool add_head(Node *head,TYPE data)
{
Node *node=create_node(data);
node->next=head->next;
head->next=node;
node->prior=head;//前驱指向头结点
return true;
}
尾添加
//尾添加
bool add_tail(Node *head,TYPE data)
{
for(Node *n=head;;n=n->next)
{
if(NULL==n->next)
{
Node *node=create_node(data);
node->next=n->next;
n->next=node;
node->prior=head;
return true;
}
}
return false;
}
按位置插入
//按位置插入
bool insert_list(Node *head,int index,TYPE data)
{
while(--index>0)
{
head=head->next;
if(NULL==head->next) return false;
}
head=head->next;
Node *node=create_node(data);
node->prior=head;
node->next=head->next;
head->next->prior=node;
head->next=node;
return true;
}
按位置删除
//按位置删除
bool delete_index(Node *head,int index)
{
Node *p=head;
if(0!=index) p=p->next;
while(--index>0)
{
p=p->next;
if(NULL==p->next) return false;
}
if(NULL==p->next->next)
{
p->next=NULL;
}
else
{
Node *temp=p->next;
p->next=temp->next;
temp->next->prior=p;
free(temp);
}
return true;
}
按值删除
//按值删除
bool delete_value(Node *head,TYPE val)
{
for(Node *n=head;n->next;n=n->next)
{
if(val==n->next->data)
{
Node *temp=n->next;
n->next=temp->next;
//n->next->prior=n;
free(temp);
return true;
}
}
return false;
}
修改
//修改
bool modify_list(Node *head,TYPE old,TYPE new)
{
for(Node *n=head->next;n;n=n->next)
{
if(old==n->data)
{
n->next->data=new;
return true;
}
}
return false;
}
访问
//访问
bool access_list(Node *head,int index,TYPE *val)
{
while(--index>0)
{
head=head->next;
if(NULL==head->next) return false;
}
*val=head->next->next->data;
return true;
}
查询
//查询
int query_list(Node *head,TYPE key)
{
int i=0;
for(Node *n=head;n->next;n=n->next,i++)
{
if(key==n->next->data) return i;
}
return -1;
}
遍历
//遍历
void show_list(Node *head)
{
for(Node *n=head->next;n;n=n->next)
{
printf("%d ",n->data);
}
printf("\n");
}
好了,下面我们浅浅的测试一下
int main(int argc,const char* argv[])
{
Node *head=create_node(0);
for(int i=0;i<5;i++)
{
add_head(head,i+1);
}
for(int i=0;i<5;i++)
{
add_tail(head,i+6);
}
//insert_list(head,3,8);
delete_index(head,9);
//delete_value(head,10);
//modify_list(head,6,66);
TYPE val;
access_list(head,6,&val);
printf("%d\n",val);
//printf("%d\n",query_list(head,66));
show_list(head);
return 0;
}
完美,双向链表的基本操作基本如上。
over