手把手寫數據結構之單向鏈表操做(一)

/**********************頭文件數據封裝及函數聲明****************/

#ifndef     _S_LIST_H
#define     _S_LIST_H

#include <stdio.h>
#include <stdlib.h>

#define PRINT        printf("LINE:    %d\n", __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!\n");
        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!\n");
        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!\n");
        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!\n");
        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!\n");
        return -1;
    }
    
    NODE *pnode = plist->head;
    if(Is_Empty_List(plist))
    {
        printf("The List is empty!\n");
        return -1;
    }

    printf("The List node count: %d\n", Get_count_Node(plist));

    while(NULL != pnode)
    {
        printf("%-5d", pnode->num);
        pnode = pnode->next;
    }

    printf("\n\n");
    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!\n");
        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!\n");
        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!\n");
        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
相關文章
相關標籤/搜索