6.6.4 结点位置的调整
我们经常会根据需要对链表中结点的位置进行相应的调整,那么在list.h中又是如何来实现的呢?下面的代码是实现结点位置调整的函数list_move()和list_move_tail()。
static inline void list_move(struct list_headlist,struct list_headhead)
{
__list_del(list->prev,list->next);
list_add(list,head);
}
static inline void list_move_tail(struct list_head*list,
struct list_head*head)
{
__list_del(list->prev,list->next);
list_add_tail(list,head);
}
在上面的代码中,list_move()函数的功能是把list移至head和head->next两个指针所指向的结点之间,而list_move_tail()函数的功能是把list移至head和head->prev两个指针所指向的结点之间。接下来还是通过一段代码来具体看看如何使用以上两个函数来实现结点位置的调整。
include<stdio.h>
include<stdlib.h>
include"list.h"
typedef struct_stu
{
char name[20];
int num;
struct list_head list;
}stu;
int main()
{
stu*pstu;
stu*tmp_stu;
struct list_head stu_list;
struct list_head*pos;
int i=0;
INIT_LIST_HEAD(&stu_list);
pstu=malloc(sizeof(stu)*5);
for(i=0;i<5;i++)
{
sprintf(pstu[i].name,"Stu%d",i+1);
pstu[i].num=i+1;
list_add(&(pstu[i].list),&stu_list);
}
list_move(&(pstu[3].list),&stu_list);
printf("把pstu[3]移至head和head->next两个指针所指向的结点之间\n");
list_for_each(pos,&stu_list)
{
tmp_stu=list_entry(pos,stu,list);
printf("student num:%d\tstudent name:%s\n",tmp_stu->num,tmp_stu->name);
}
list_move_tail(&(pstu[2].list),&stu_list);
printf("把pstu[2]移至head和head->prev两个指针所指向的结点之间\n");
list_for_each(pos,&stu_list)
{
tmp_stu=list_entry(pos,stu,list);
printf("student num:%d\tstudent name:%s\n",tmp_stu->num,tmp_stu->name);
}
free(pstu);
return 0;
}
运行结果:
root@ubuntu:/home/paixu/dlist_node#./a
把pstu[3]移至head和head->next两个指针所指向的结点之间
student num:4 student name:Stu4
student num:5 student name:Stu5
student num:3 student name:Stu3
student num:2 student name:Stu2
student num:1 student name:Stu1
把pstu[2]移至head和head->prev两个指针所指向的结点之间
student num:4 student name:Stu4
student num:5 student name:Stu5
student num:2 student name:Stu2
student num:1 student name:Stu1
student num:3 student name:Stu3
这里需要提醒读者注意的是,pstu[]的下标是从0开始的,所以pstu[3]对应的是stu4。从运行结果可以看出,上面的代码成功地实现了对结点在链表中位置的调整。