C语言单链表的算法之逆序

一:什么是链表的逆序

        (1)链表的逆序又叫反向,意思就是把链表中所有的有效节点在链表中的顺序给反过来

二:单链表逆序算法分析

        (1)当需要对一个数据结构进行操作时,就有必要有一套算法。这就是数据结构和算法的关系

        (2)算法的两个层次:第一个层次是数学和逻辑上的算法;第二个层次是编程语言来实现算法

        (3)从逻辑上来讲,链表的逆序有很多种方法。这些方法最终都能实现需要,但是效率是一样的。彼此的可扩展性容错性等不同

        (4)思路:首先先遍历节点,然后将原链表中的头指针头节点作为新链表的头指针头节点,再将原链表中的有效节点挨个依次取出来,采用头部插入的方法插入进新链表

        (5)链表逆序 = 遍历 + 头插入

三:逆序代码实现

       (1)实现函数


/****************************************
函数名:reverse
作用:将链表进行反向排序
返回值:无
参数:ph 链表头指针
****************************************/
void reverse(struct node *ph)
{


    strucct node *p = ph->pNEXT;
    STRUCT NODE *pback = ph;


    if((p == NULL) || (p->pNEXT == NULL))     //判断是否是只有一个节点还是没有有效节点
        {
            
            return;            //当链表中只有一个节点或没有有效节点时不需要操作

        }

    

    //当链表有两个或两个以上的节点才需要进行操作
    while(NULL != p->pNEXT)    //判断是不是最后一个节点
        {

                back = p->pNEXT;     //保存p节点后的一个节点
                if(p == ph->pNEXT)
                    {
                        //原链表的第一个有效节点,在逆序之后会变成尾节点,将这个节点的
                        //指针指向NULL
                        p->pNEXT = NULL;

                    }
                else
                    {
                            //不是原链表的第一个有效节点,指向上一个头节点指向的节点地址
                            p->pNEXT = ph->pNEXT;   
                            


                    }
                
                    ph->pNEXT = p;    //头节点指向新插入的节点

                    p = pback;        //将下一个要插入的节点的地址给指针临时变量


        }


        //在进行遍历时判断条件是不是最后一个节点,这样会丢失最后一个节点
            

        insert_head(ph,p->pNEXT);





}

(2)程序源码

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
 
struct node
{
 
    int datas;
    struct node *pNEXT;
 
 
};
 
struct node *create(int a)
{
 
 
    struct node *p = (struct node *)malloc(sizeof(struct node));
 
    if(NULL == p)
        {
            printf("malloc error!\n");
 
            return NULL;
 
        }
 
      memset(p,0,sizeof(struct node));  
      //bzero(p,sizeof(struct node));
 
      p->datas = a;
      p->pNEXT = NULL;
 
 
      return p;
 
 
}
 
 
 
void insert_tail(struct node *phead,struct node *new)
{
 
    struct node *p = phead;
    int cat = 0;
    while(NULL !=  p->pNEXT)
        {
 
 
            p = p->pNEXT;
            cat++;
 
        }
 
        p->pNEXT = new;
        phead->datas = cat +1;
 
 
}
 
 
 
void insert_head(struct node *head,struct node *new)
{
 
    new->pNEXT =  head->pNEXT;
 
    head->pNEXT = new;
 
    head->datas += 1;
 
}
 
void ergodic(struct node *ph)
{
 
 
        struct node *p = ph;
        int cat = 0;
 
        printf("datas number is a: %d\n",p->datas);
 
        while(NULL !=  p->pNEXT)
            {
                cat++;
                printf("datas number is :%d\n",cat);  
                p = p->pNEXT;  
                printf("datas is: %d\n",p->datas);    
                
 
 
 
 
            }
 
        
 
 
}
 
 
int delete(struct node *ph,int data)
{
 
    struct node *p = ph;
    struct node *prev = NULL;
    int cat = 0;
    while(NULL !=  p->pNEXT)
            {
                prev = p;
                p = p->pNEXT; 
                if(p->datas == data)
                    {
 
                        if(NULL == p->pNEXT)
                            {       
                
                                prev->pNEXT  = NULL;
                                free(p);
                                cat = ph->datas;
                                ph->datas = cat -1;
                            }
                        else
                            {
                                prev->pNEXT  = p->pNEXT;
                                free(p);
                                cat = ph->datas;
                                ph->datas = cat -1;
 
                            }   
 
                            return 0;
 
                    }    
 
 
                 
                                         
 
            }
 
            return -1;
 
 
}


void reverse(struct node *ph)
{


    strucct node *p = ph->pNEXT;
    STRUCT NODE *pback = ph;


    if((p == NULL) || (p->pNEXT == NULL))     //判断是否是只有一个节点还是没有有效节点
        {
            
            return;            //当链表中只有一个节点或没有有效节点时不需要操作

        }

    

    //当链表有两个或两个以上的节点才需要进行操作
    while(NULL != p->pNEXT)    //判断是不是最后一个节点
        {

                back = p->pNEXT;     //保存p节点后的一个节点
                if(p == ph->pNEXT)
                    {
                        //原链表的第一个有效节点,在逆序之后会变成尾节点,将这个节点的
                        //指针指向NULL
                        p->pNEXT = NULL;

                    }
                else
                    {
                            //不是原链表的第一个有效节点,指向上一个头节点指向的节点地址
                            p->pNEXT = ph->pNEXT;   
                            


                    }
                
                    ph->pNEXT = p;    //头节点指向新插入的节点

                    p = pback;        //将下一个要插入的节点的地址给指针临时变量


        }


        //在进行遍历时判断条件是不是最后一个节点,这样会丢失最后一个节点
            

        insert_head(ph,p);





}
 
 
 
int main(void)
{
    struct node *phead = create(0);
 
    insert_tail(phead,create(12));   
    insert_tail(phead,create(13));
    insert_tail(phead,create(14));
 
    ergodic(phead);     //遍历打印各个节点数据区
 
    reverse(phead);   //将链表进行逆序
 
   
 
    ergodic(phead);    //再次遍历打印各个节点数据区
 
        
      return 0;
 
 
}

运行结果:

 

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值