这个小程序的问题发出了都怪不好意思。。先谢谢大家了。。。。。
/*
先说说我要干的吧。。最终目的就是要逆置 一个带头结点的 单链表
大家帮我看看程序错误是不是因为前面的几个函数的问题,还是最后的逆置操作问题
*/
#include<stdio.h>
#include<malloc.h>
struct list
{
int data;
struct list *next;
};
// 带头结点的单链表
list * Input()
{
list *p, *r, *head;
int ch;
int num;
num = 0;
head = (list *) malloc(sizeof(list));
r = head;
printf("输入数据:\n");
scanf("%d", &ch);
while(ch != 0)
{
num ++;
p = (list *) malloc(sizeof(list));
p->data = ch;
r->next = p;
r = p;
printf("继续输入数据:\n");
scanf("%d", &ch);
}
head->data = num;
r->next =NULL;
printf("输入结束~\n");
return head;
}
// 输出函数
void Output(list *head)
{
list *p;
p = head->next;
while(p != NULL)
{
printf("%d \n", p->data);
p = p->next;
}
printf("链表中共有%d个数据\n", head->data);
}
//逆置单链表
/*
这个函数 还有个缺陷。。就是只能操作偶数个数据的链表,奇数的还不行,,刚刚发现的。。大家先帮我看看偶数的情况
先说下我的算法。。哦不。顶多算个方法。。。
通过交换前后对应的俩个结点的数据data部分 和 地址 next 部分 实现 最后逆置单链表。。
具体的通过 while循环 控制的大循环的次数,在用for循环来控制 后面结点的指针 然后交换数据和地址
*/
list * Over(list *head)
{
list *p, *q, *r;
int num, znum;
int i, h;
int j;
i = 1;
num = head->data;
znum = num/2; //计算共需要配对前后交换多少次
p = head->next;
q = p;
while(i <= znum)
{
for(h = i; h < num; h++) // 查找 后面的指针
{
q = q->next;
}
j = p->data;
p->data = q->data;
q->data = j;
r = p->next;
p->next = q->next;
q->next = r;
p = p->next;
q = head->next;
i++;
}
return head;
}
void main()
{
list *head, *nhead;
head = Input();
Output(head);
Output(Over(head));
}
// 大家帮忙看看吧。。我实在是郁闷了。。谢谢大家了。。程序写的 不咋地。。辛苦了。
[解决办法]
你思路太复杂了.
链表一倒置只需要将指针倒过来指向.
即之前是A->B的,变为B->A这样的就好.
而且最后 头结点指向空,尾节点指向前一个节点就好
或者假设有一个新链表,将原来的链表从头到尾一次插入到新链表的头部就好.
这里是第二种思路的代码
- C/C++ code
list* Over(list* head){list *newhead=head;list *cur=head->next;newhead->next=0;list *post;while(cur){post=cur->next;cur->next=newhead->next;newhead->next=cur;curr=post;}return newhead;}
[解决办法]
感觉你的方法有些复杂 用头插法将之逆置 我把Over重写了下 思路就是头插法 从第一个元素后取出查到头结点和第一个元素之间。
list * Over(list *head)
{
list *p, *q, *r;
int i, h,num;
num = head->data;
p=head->next;
q=p->next;
for(i=1;i<num;i++)
{
if(q->next!=NULL)
r=q->next;
else
r=q;
p->next=NULL;
q->next=head->next;
head->next=q;
q=r;
}
return head;
}