
#include<stdioh>
#include<stdlibh>
#include <malloch>
typedef struct LNode
{ int data;
struct LNode next;
} LNode, Linklist;
//创建链表
Linklist create()
{ int i,n; //i用于下面循环,n用来存放有效节点的字数
Linklist p,L;
printf("Please input N =");
scanf("%d",&n);
L= (Linklist)malloc(sizeof(LNode)); // 分配一个不存放有效数据的头结点
L->next=NULL;
for(i = 0; i < n; i++)
{ p = (Linklist)malloc(sizeof(LNode));//生成新节点
scanf("%d",&p->data);//输入元素值
p->next = L->next;
L->next = p;
}
return L; //返回头节点 ;
}
//链表反转输出
Linklist ReverseList(Linklist L,int st) //st为1时输出结点数据
{ if(L->next!= NULL)
ReverseList(L->next,1);
if(st)printf("%d ", L->data);
return L;
}
void put(Linklist L)
{ Linklist p;
p = L->next;
while(p != NULL)
{ printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
int main()
{ Linklist L;
L=create();
printf("A: "); put(L);
printf("B: ");
ReverseList(L,0); //附加结点未保存数据,故第二参数为0
return 0;
}
nizhi()函数改动如下:
void nizhi(LINKLISTL) //补充此函数
{
SeqStack S;
LINKLIST q;
q = (L)->next;
InitStack(&S);
while(q)
{
if (Push(&S, q))
q = q->next;
}
printf("开始逆序输出……\n");
while(!IsEmpty(S))
{
Pop(&S, &q);
printf("%3c", q->data);
}
printf("\n逆序输出完成\n");
}
现在可以在nizhi()函数中生成逆序节点。
但是不能保存到原链表中去,那样就会覆盖原先节点的值。
如果要得到逆置的链表,就得生成另一个新的链表,可以这样做:
void nizhi(LINKLISTL) //补充此函数
{
SeqStack S;
LINKLIST q, head, r, p;
q = (L)->next;
InitStack(&S);
while(q)
{
if (Push(&S, q))
q = q->next;
}
printf("开始逆置到新链表中……");
head=(LINKLIST )malloc(sizeof(NODE));//创建新链表的头结点
r = head;
while(!IsEmpty(S))
{
Pop(&S, &q);
p = (NODE )malloc(sizeof(NODE));
p->data = q->data;
r->next = p;
r = p;
}
r->next=NULL;
L = head;
printf("逆置完成\n");
}
现在功能完全实现了,但是原先程序和这段代码都没有考虑释放已经分配的内存,所以会造成内存泄漏,需要继续完善。
void reverse(linklist &L)
{
linklist p = NULL, q = L;
while(q != NULL){
L = q->next; // 保留下一个节点
q->next = p;
p = q;
q = L; // 移动到下一个节点
}
L = p; // 指向逆置后的头节点
}
尽管程序不全,没有看到pa变量的类型,但是,仍然可以判定当pa变量的值为0时while循环终止。在c语言中,常量NULL的值就是0。也就是说,当pa的值是NULL时,循环就终止了。有什么问题请留言
大概看了一下,程序主要部分是while循环,前面是一些初始化,跟定义一些东西
如果没看错的话 p应该是预先指向要倒置的链表的第一个结点倒置后,q为新链表的头
没有图比较难说明,我给你说出两步,之后的你自己推
1 2表示两个结点1的后面连接的是2
1表示头,当前p指向1;
q=p让q也指向1
p=p->link;p现在指向2了
q->link=first q的下一个为first当前为空
first=q first也指向了1
之后判断while
成立继续
q=p q现在指向2
p=p->link 假设3为2后面的连接,那么p现在就指向3
q->link=first q的下一个指向1//这步是关键,你想想,循环两次后 q指向2 而q->link指向1 实现了倒置
first=q first指向2
之后继续while判断
你最后拿张纸自己画画
#include <stdioh>
#include<stdlibh>
#define stacksize 100
typedef int datatype;//这里所谓的datatype关键字是不存在的,所以这里用typedef (类型定义) 定义成int 型,意思是datatype 就是int
typedef struct
{
datatype data[stacksize];
int top;
}seqstack;//这里定义了栈(其实就是结构体,里面有个int型的数组和int型的成员),在下面有栈的一些运算,
typedef struct node
{
datatype data;
struct node next;
}listnode;//这里定义了链表。int 型成员和 node 指针
typedef listnode linklist;//定义linklist指针,就是listnode 类型的指针
linklist h;
linklist p;
int x;
linklist creatlist(int n) //这里是创建链表
{
linklist h;
listnode p1,p2;
int i;
h=(linklist)malloc(sizeof(listnode));/这里是为 h 这个结点(或者可称为结构体,它本来的面目),申请内存空间,大小就是(sizeof(listnode),就是结构体所占大小)/
h->next=NULL; /逆置单链表初始为空/
p2=h;
printf("请输入链记录!:\n");
for(i=0;i<n;i++)//这里就输入n个记录,比如1,2,3,4,5
{
p1=(linklist)malloc(sizeof(listnode));//同上
scanf("%d",&p1->data);//输入该节点中的数据成员data的值
p1->next=p2->next; /将当前处理节点p插入到逆置L的表头/
p2->next=p1;
p2=p1; /p指向下一个待插入的节点/
}
return (h);
}
void print(linklist h,int n)//将该链表打印出来
{
if(h==NULL)
printf("链表为空!\n");
printf("这%d个链记录是:\n",n);
p=h->next;
printf("%d",p->data);
x=1;
while(p->next!=NULL)
{
x++;
p=p->next;
printf("%4d",p->data);//这里就是P指针一直指向next, 循环打印,直到p=NULL
if(!(x%10))
printf("\n");// - -这里应该是每打印10次就换行的意思。
}
}
datatype push(seqstack s,int x) /这里就是栈的 *** 作,进栈,返回类型为datatype,实际上就是int,这里说下参数,第一个参数是指向栈的指针类型,第二个参数是你要进栈的值/
{
if(s->top==stacksize-1)//超出栈的大小
printf("堆栈溢出!\n");
else
s->data[++s->top]=x;
}
datatype pop(seqstack s) //和上面相同,这个是出栈,return 栈的元素的值
{
if(s->top==-1)
printf("堆栈为空!\n");
else
return (s->data[s->top--]);
}
datatype deleted(linklist h)//删除链表结点的值,并将该结点中data值放到temp
{
datatype temp;
linklist p;
p=h->next;
temp=(p->data);
h->next=p->next;
free(p);//这步重要!释放结点所占的空间
return (temp);
}
void invertedlist(linklist h,int n)//
{
seqstack s;
int i,j,temp;
stop=-1;
for(i=0;i<n;i++)//说白了就是将链表的值依次进栈
{
temp=deleted(h);
push(&s,temp);
}
for(i=0;i<n;i++)//然后将各个值依次出栈
{
temp=pop(&s);
printf("%5d",temp);
if(!((i+1)%10))
printf("\n");
}
printf("\n");
}
main()
{
linklist h;
int n;
printf("请输入n的值:\n");
scanf("%d",&n);
h=creatlist(n);
print(h,n);
printf("\n");
printf("经过逆置,链记录为:\n");
invertedlist(h,n);
system("pause");
return 0;
}
最后总结,原理就是利用栈的先进后出的特性来实现逆置的。有什么不懂可以再提问。以上就是关于C语言用链表实现逆序输出全部的内容,包括:C语言用链表实现逆序输出、写出一个借助于栈将一个单链表逆置的C语言函数 我做的这个程序有错误,但不知道怎么改求解!谢谢!、下面是用c语言编写的对不带头结点的单链表进行就地逆置的算法,求大神详细解释等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)