• 手把手写数据结构之单向链表操作(一)


    /**********************头文件数据封装及函数声明****************/
    
    #ifndef     _S_LIST_H
    #define     _S_LIST_H
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #define PRINT        printf("LINE:    %d
    ", __LINE__);
    
    /*单链表的实现可以各有不同,只要该实现,符合链表的定义即可。
     *单链表最重要的数据结构是元素结点,
     *最重要的操作是插入结点,删除结点和遍历。
     *其它的操作基本上是这3个操作的组合,依据具体的要求而定。
    */
    
    /*******************************************
    *单向链表结点信息
    *
    *数据域:    可以是普通类型,也可以是封装类型
    *指针域:    next指针
    *
    *********************************************/
    typedef struct node
    {
        int num;            //数据域
        struct node *next;    //指针域
    }NODE;
    
    /*******************************************
    *单向链表信息
    *
    *链表的属性信息: 链表的作用描述,链表当前节点个数等等
    *指针信息:        一般必须有表头指针,也可以有为结点指针
    *
    *********************************************/
    typedef struct list_info
    {
        int max;            //结点个数
        NODE *head;            //头结点指针
    }LIST_INFO;
    
    /********************************************
    *Des:  创建链表
    *Ret:  成功返回0, 失败返回-1;    
    *********************************************/
    int Create_List(LIST_INFO **plist);
    
    /********************************************
    *Des:  判断链表是否为空
    *Ret:  真: 1,  假: 0    
    *********************************************/
    int Is_Empty_List(const LIST_INFO *plist);
    
    /********************************************
    *Des:  添加新的数据节点到表头
    *Ret:  成功返回0, 失败返回-1;    
    *********************************************/
    int AddtoList_Head(LIST_INFO *plist, const int num);
    
    /********************************************
    *Des:  添加新的数据结点到表尾
    *Ret:  成功返回0, 失败返回-1;    
    *********************************************/
    int AddtoList_Tail(LIST_INFO *plist, const int num);
    
    
    /********************************************
    *Des:    查找某个结点是否存在,存在返回前一个结点
    *Ret:    NULL:不存在或出错,(NODE *)1:该节点为头结点    
    *********************************************/
    NODE * Find_Node(const LIST_INFO *plist, const int num);
    
    
    /********************************************
    *Des:      获取第m结点的数据
    *Ret:    成功返回0,失败返回-1
    *********************************************/
    int Get_Node_Info(const LIST_INFO *plist, int *num, const int M);
        
    
    
    /********************************************
    *Des:    将新的数据num插入到数据域为dest_num结点前面
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Insert_num_to_Node(LIST_INFO *plist, const int num, const int dest_num);
    
    
    /********************************************
    *将新的数据结点添加到第m个结点后
    *成功返回0,返回-1;    
    *********************************************/
    int Add_num_to_M(LIST_INFO *plist, const int m, const int num);
    
    
    /********************************************
    *Des:    删除第一个数据与为num的结点
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Delete_num_from(LIST_INFO *plist, const int num);
    
    
    /********************************************
    *Des:    遍历链表
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Traverse_List(const LIST_INFO *plist);
    
    /********************************************
    *Des:    将链表所有节点排序(按数据从小到大)
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Order_List(LIST_INFO *plist);
    
    /********************************************
    *Des:    清空链表
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Empty_List(LIST_INFO *plist);
    
    
    /********************************************
    *Des:    将链表逆序
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Reverse_List(LIST_INFO *plist);
    
    
    /********************************************
    *Des:    获取链表结点个数
    *Ret:    成功返回结点个数,失败返回-1;    
    *********************************************/
    int Get_count_Node(const LIST_INFO *plist);
    
    /********************************************
    *Des:    销毁链表
    *Ret:    成功返回0,失败返回-1;    
    *********************************************/
    int Destory_List(LIST_INFO **plist);
    
    
    /********************************************
    *Des:    顺序表结点插入 (已经按从小到大排好序的链表)
    *Ret:    成功返回0,失败返回-1;    
    *********************************************/
    int Order_Insert__Node(LIST_INFO * plist, const int num);
    
    
    
    
    #endif
    
    
    
    /***************************函数定义的实现********************/
    #include "s_list.h"
    
    /********************************************
    *Des:  创建结点并填充结点信息
    *Ret:  成功返回结点, 失败返回NULL;    
    *********************************************/
    static NODE *__Create_Node__(int num)
    {
        NODE *new_node = (NODE *)malloc(sizeof(NODE));
        if(NULL == new_node)
        {
            perror("Malloc new node");
            return NULL;
        }
    
        new_node->num = num;
        new_node->next = NULL;
    
        return new_node;
    }
    
    /********************************************
    *Des:  创建链表
    *Ret:  成功返回0, 失败返回-1;    
    *********************************************/
    int Create_List(LIST_INFO **plist)
    {
        if(NULL == plist)
            return -1;
        *plist = (LIST_INFO *)malloc(sizeof(LIST_INFO));
        if(NULL == *plist)
        {
            perror("List malloc");
            return -1;
        }
    
        (*plist)->head = NULL;
        (*plist)->max = 0;
    
        return 0;
    }
    
    /********************************************
    *Des:  判断链表是否为空
    *Ret:  真: 1,  假: 0    
    *********************************************/
    int Is_Empty_List(const LIST_INFO *plist)
    {
        return (NULL == plist->head) ? 1: 0;
    }
    
    /********************************************
    *Des:  添加新的数据节点到表头
    *Ret:  成功返回0, 失败返回-1;    
    *********************************************/
    int AddtoList_Head(LIST_INFO *plist, const int num)
    {
        NODE *new_node = __Create_Node__(num);
        if(NULL == new_node)
            return -1;
    
        new_node->next = plist->head;
        plist->head = new_node;
    
        plist->max++;
    
        return 0;
    }
    
    /********************************************
    *Des:  添加新的数据结点到表尾
    *Ret:  成功返回0, 失败返回-1;    
    
    *********************************************/
    int AddtoList_Tail(LIST_INFO *plist, const int num)
    {
        NODE *pnode = plist->head, *tmpnode = NULL;
        NODE *new_node = __Create_Node__(num);
        if(NULL == new_node)
            return -1;
    
        //链表为空
        if(Is_Empty_List(plist))
        {
            plist->head = new_node;
        }
        else
        {
            while(NULL != pnode->next)
            {
                pnode = pnode->next;
            }
            pnode->next = new_node;
        }
    
        plist->max++;
    
        return 0;
    }
    
    
    /********************************************
    *Des:    查找某个结点是否存在,存在返回前一个结点
    *Ret:    NULL:不存在或出错,(NODE *)1:该节点为头结点    
    *********************************************/
    NODE * Find_Node(const LIST_INFO *plist, const int num)
    {
        NODE *pre_node = (NODE *)1;
        NODE *tmpnode = NULL, *pnode = plist->head;
        while(NULL != pnode)
        {
            if(pnode->num == num)
                return pre_node;
            
            pre_node = pnode;
            pnode = pnode->next;
        }
    
        return NULL;
    }
    
    
    /********************************************
    *Des:      获取第m结点的数据
    *Ret:    成功返回0,失败返回-1
    *********************************************/
    int Get_Node_Info(const LIST_INFO *plist, int *num, const int M)
    {
        int idx = 0;
        if(M > Get_count_Node(plist) || M <= 0)
        {
            printf("Invalid arg!
    ");
            return -1;
        }
    
        NODE *pnode = plist->head;
        while(NULL != pnode)
        {
            idx++;
            if(idx == M)
                break;
            
            pnode = pnode->next;
        }
        *num = pnode->num;
        
        return 0;
    }
        
    /********************************************
    *将新的数据结点添加到第m个结点后
    *成功返回0,返回-1;    
    *********************************************/
    int Add_num_to_M(LIST_INFO *plist, const int m, const int num)
    {
        int idx = 0;
        if(m > Get_count_Node(plist) || m <= 0)
        {
            printf("Invalid arg!
    ");
            return -1;
        }
        
        NODE *new_node = __Create_Node__(num);
        if(NULL == new_node)
        {
            return -1;
        }
        NODE *pnode = plist->head;
        
        while(NULL != pnode)
        {
            idx++;
            if(idx == m)
                break;    
            pnode = pnode->next;
        }
    
        new_node->next = pnode->next;
        pnode->next = new_node;
        plist->max++;
        
        return 0;
    }
    
    /********************************************
    *Des:    将新的数据num插入到数据域为dest_num结点前面
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Insert_num_to_Node(LIST_INFO *plist, const int num, const int dest_num)
    {
        //查找dest_num结点
        NODE *pre_node = Find_Node(plist, dest_num);
        if(NULL == pre_node)
        {
            printf("No such node!
    ");
            return -1;
        }
    
        //创建结点
        NODE *new_node = __Create_Node__(num);
        if(NULL == new_node)
        {
            return -1;
        }
        //若插入到表头
        if(pre_node == (NODE *)1)
        {
            new_node->next = plist->head;
            plist->head = new_node;
        }
        else//插入到其他位置
        {
            new_node->next = pre_node->next;
            pre_node->next = new_node;
        }
    
        plist->max++;
        return 0;
            
    }
    
    
    /********************************************
    *Des:    删除第一个数据与为num的结点
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Delete_num_from(LIST_INFO *plist, const int num)
    {
        NODE *fnode = NULL;
        NODE *prev_node = Find_Node(plist, num);
        if(NULL == prev_node)
        {
            printf("Have no such Node!
    ");
            return -1;
        }
    
        if((NODE *)1 == prev_node)
        {
            fnode = plist->head;
            plist->head = fnode->next;
        }
        else
        {
            fnode = prev_node->next;
            prev_node->next = fnode->next;
        }
    
        free(fnode);
        plist->max--;
    
        return 0;
    }
    
    
    /********************************************
    *Des:    遍历链表
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Traverse_List(const LIST_INFO *plist)
    {
        //函数入口检测
        if(NULL == plist)
        {
            printf("Invalid arg!
    ");
            return -1;
        }
        
        NODE *pnode = plist->head;
        if(Is_Empty_List(plist))
        {
            printf("The List is empty!
    ");
            return -1;
        }
    
        printf("The List node count: %d
    ", Get_count_Node(plist));
    
        while(NULL != pnode)
        {
            printf("%-5d", pnode->num);
            pnode = pnode->next;
        }
    
        printf("
    
    ");
        return 0;
    }
    
    /********************************************
    *Des:    将链表所有节点排序(按数据从小到大)
    *Ret:    成功返回0,返回-1;    (没有想出更好方法)
    *********************************************/
    int Order_List(LIST_INFO *plist)
    {
        NODE *pnode = plist->head->next, *head = plist->head;
        head->next = NULL;
        NODE *tmpnode = NULL, *pre_p = NULL, *tmp = NULL;
        
        while(pnode != NULL)
        {
            tmp = pnode->next;
            
            tmpnode = head;
            if(pnode->num <= head->num)
            {
                pnode->next = head;
                head = pnode;
            }
            else
            {
                pre_p = head;
                tmpnode = head->next;
                while(tmpnode != NULL)
                {
                    if(pnode->num <= tmpnode->num)
                    {
                        break;
                    }
                    pre_p = tmpnode;
                    tmpnode = tmpnode->next;
                }
                pre_p->next = pnode;
                pnode->next = tmpnode;
            }
    
            pnode = tmp;    
        }
    
        plist->head = head;
    
        return 0;
    }
    
    
    /********************************************
    *Des:    清空链表
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Empty_List(LIST_INFO *plist)
    {
        if(NULL == plist)
        {
            printf("Invalid arg!
    ");
            return -1;
        }
    
        NODE *fnode = NULL, *pnode = plist->head;
        while(NULL != pnode)
        {
            fnode = pnode;
            pnode = pnode->next;
            free(fnode);
        }
    
        plist->head = NULL;
        plist->max = 0;
    
        return 0;
    }
    
    
    /********************************************
    *Des:    将链表逆序
    *Ret:    成功返回0,返回-1;    
    *********************************************/
    int Reverse_List(LIST_INFO *plist)
    {
        if(NULL == plist)//函数入口检测
        {
            printf("Invalid arg!
    ");
            return -1;
        }
        
        NODE *head = NULL, *tmpnode = NULL, *pnode = plist->head;
        while(NULL != pnode)
        {
            tmpnode = pnode;
            pnode = pnode->next;
    
            tmpnode->next = head;
            head = tmpnode;
        }
    
        plist->head = head;
    
        return 0;
    }
    
    /********************************************
    *Des:    顺序表结点插入 (已经按从小到大排好序的链表)
    *Ret:    成功返回0,失败返回-1;    
    *********************************************/
    int Order_Insert__Node(LIST_INFO * plist, const int num)
    {
        if(NULL == plist)//函数入口检测
        {
            printf("Invalid arg!
    ");
            return -1;
        }
    
        NODE *pnode = NULL, *tmpnode = NULL;
        NODE *new_node = __Create_Node__(num);//创建新的结点
        if(NULL == new_node)
            return -1;
    
        pnode = plist->head;
    
        //链表为空
        if(plist->head == NULL)
        {
            plist->head = new_node;
        }
    
        //第一个结点就大于num
        else if(plist->head->num > num)
        {
            new_node->next = plist->head;
            plist->head = new_node;
        }
        else 
        {
            tmpnode = plist->head;
            pnode = plist->head->next;
            
            while(NULL != pnode)
            {
                if(pnode->num > num)
                    break;
                tmpnode = pnode;
                pnode = pnode->next;
            }
            new_node->next = tmpnode->next;
            tmpnode->next = new_node;
        }
    
        plist->max++;
    
        return 0;
    }
    
    
    /********************************************
    *Des:    获取链表结点个数
    *Ret:    成功返回结点个数,失败返回-1;    
    *********************************************/
    int Get_count_Node(const LIST_INFO *plist)
    {
        return plist->max;
    }
    
    /********************************************
    *Des:    销毁链表
    *Ret:    成功返回0,失败返回-1;    
    *********************************************/
    int Destory_List(LIST_INFO **plist)
    {
        if(Empty_List(*plist) < 0)
            return -1;
    
        free(*plist);
        *plist = NULL;
    
        return 0;
    }
    View Code
  • 相关阅读:
    asp.net mvc(2013424)——基本知识
    asp.net mvc(2013425)——使用模板页
    jquery实现tab切换核心代码
    asp.net mvc(2013422 )——准备入门
    也说C#串行化
    Net Assembly.GetExecutingAssembly() 和 Assembly.GetCallingAssembly()的区别
    log (一)
    C# 重载和从写的区别
    log4net
    C# 反射
  • 原文地址:https://www.cnblogs.com/xuyh/p/3231162.html
Copyright © 2020-2023  润新知