C语言用链表实现逆序输出

C语言用链表实现逆序输出,第1张

#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语言编写的对不带头结点的单链表进行就地逆置的算法,求大神详细解释等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/9417969.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-28
下一篇2023-04-28

发表评论

登录后才能评论

评论列表(0条)

    保存