内核链表实现数据奇偶重排
用内核链表实现奇偶重排,在不同情况下,可以根据其相关规律进行排序,以下的排序要求为:偶数排前(降序),奇数排后(升序)。
例如:
假设你输入的是 10 45 89 55 41 8 100
排列后的结果 100 10 8 41 45 55 89
- 首先我们可以先把输入的数据由小到大排列
- 其次再通过内核链表 list_for_each(pos, &head->mypoint)向前遍历,通过list_move(pos, &head->mypoint);把偶数移动到head的前面,最后完美解决问题。
详细代码如下:
#include "myhead.h"
#include "kernel_list.h"
//奇偶重排
//定义一个结构体表示内核链表的节点
typedef struct kerlist
{
//数据域
int data;
//指针域
struct list_head mypoint;
}klist;
//初始化内核链表的表头
klist *init_list()
{
klist *head=malloc(sizeof(klist));
//初始化指针
INIT_LIST_HEAD(&(head->mypoint));
return head;
}
//初始化节点
klist *new_node(int newdata)
{
klist *newnode=malloc(sizeof(klist));
newnode->data=newdata;
//初始化指针
INIT_LIST_HEAD(&(newnode->mypoint));
return newnode;
}
void reorder(klist *head)
{
struct list_head *pos, *k=head->mypoint.next;
klist *p;
// pos将会从head开始,逐个往后遍历每个小结构体
list_for_each(pos, &head->mypoint)
{
// 从小结构体pos,获取对应的大结构体p
p = list_entry(pos, klist, mypoint);
if(p->data%2 == 0) // 偶数
{
// 将pos移动到链表的开头
list_move(pos, &head->mypoint);
pos = k;
}
else // 奇数
k = pos;
}
}
int change(klist *q,klist *p)
{
int tem;
tem=q->data;
q->data=p->data;
p->data=tem;
return 0;
}
void show(klist * myhead)
{
if(list_empty(&myhead->mypoint))
{
printf("链表为空\n");
return;
}
klist *pos;
list_for_each_entry(pos, &myhead->mypoint, mypoint)
{
printf("%d\t", pos->data);
}
printf("\n");
}
int main()
{
//初始化头结点
klist *myhead=init_list();
int indata,n =8;
for(int i=0; i<n; i++)
{
printf("请输入节点数据:");
scanf("%d",&indata);
// a. 创建新节点new
klist *new = new_node(indata);
list_add_tail(&new->mypoint, &myhead->mypoint);
}
//打印
printf("链表中的数据为:");
show(myhead);
//把所有数据升序排列
klist *p;
int x=0;//x为循环次数,此处可以通计算详细得出次数
int y=1;
while(x<20)
{
klist *q=myhead;
list_for_each_entry(p,&(myhead->mypoint),mypoint)
{
//y为标记数,它的存在保证p在q的前面
if(y==1)
y=0;
else if(q->data > p->data)
{
change(q,p);
}
q = p;
}
x++;
}
printf("升序后数据表为:");
show(myhead);
reorder(myhead);
printf("排序后的数据为:");
show(myhead);
return 0;
}
以上算法仅供参考!