zoukankan      html  css  js  c++  java
  • 手把手写数据结构之单向链表操作(一)

    /**********************头文件数据封装及函数声明****************/
    
    #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
  • 相关阅读:
    leetcode 155. Min Stack 、232. Implement Queue using Stacks 、225. Implement Stack using Queues
    leetcode 557. Reverse Words in a String III 、151. Reverse Words in a String
    leetcode 153. Find Minimum in Rotated Sorted Array 、154. Find Minimum in Rotated Sorted Array II 、33. Search in Rotated Sorted Array 、81. Search in Rotated Sorted Array II 、704. Binary Search
    leetcode 344. Reverse String 、541. Reverse String II 、796. Rotate String
    leetcode 162. Find Peak Element
    leetcode 88. Merge Sorted Array
    leetcode 74. Search a 2D Matrix 、240. Search a 2D Matrix II
    Android的API版本和名称对应关系
    spring 定时任务执行两次解决办法
    解析字符串为泛型的方法
  • 原文地址:https://www.cnblogs.com/xuyh/p/3231162.html
Copyright © 2011-2022 走看看