1. 程式人生 > >資料結構-c語言實現連結串列的建立,增刪,翻轉

資料結構-c語言實現連結串列的建立,增刪,翻轉

很經典的課題了,這裡直接給出源程式:

#include <stdio.h>
#include <stdlib.h>
#define LIST_MAX_LEN 10

typedef int ElementType;
typedef int BOOL;
#define TRUE 1
#define FALSE 0

typedef struct node
{
    ElementType data;
    struct node *next;
}Node,*pNode;

void InitNode(pNode pl)
{
    if (pl==NULL)
    {
        return;
    }
    pl->next=NULL;
}

pNode TraverseList(pNode pl,int num)
{
    printf("遍歷連結串列:\n");
    int index=0;
    pNode temp=(pNode)malloc(sizeof(Node));
    if (temp==NULL)
    {
        return pl;
    }else
    {
        temp=pl->next;
    }
    while(temp!=NULL && (index<num))
    {
        printf("%d\t",temp->data);
        temp=temp->next;
        index++;
    }
    printf("\n");
    return temp;
}

void CreateList(pNode pl ,int num)
{
    if (num<=0)
    {
        return;
    }
     printf("開始建立連結串列:\n");
    for (int i=0;i<num;i++)
    {
        pNode new = (pNode)malloc(sizeof(Node));

        if (new==NULL)
        {
            return;
        }
        new->data=i;
        new->next=pl->next;
        pl->next=new;
    }
    printf("address pl=%d",pl);
    printf("連結串列建立成功。\n");
}

 BOOL InsertList(pNode pl,int num,int index,int *list_len)
 {
    if (index >=*list_len)
    {
        printf("插入的位置超過連結串列最大長度\n");
        return FALSE;
    }
    pNode node_index = (pNode)malloc(sizeof(Node));
    if (node_index==NULL) return FALSE;

    if (index==0)//在表頭插入
    {
        node_index=pl;
    } else
    {
        //遍歷到指定index 的位置的上一個位置
        node_index = TraverseList(pl,index-1);
    }

    //建立新節點
    pNode new= (pNode)malloc(sizeof(Node));
    if (new==NULL) return FALSE;
    //插入新節點
    new->data=num;
    new->next=node_index->next;
    node_index->next=new;
   // printf("node_index:data:%d\n",node_index->data);
    (*list_len)+=1;
    return TRUE;

 }
BOOL DeleteList(pNode pl,int index,int *list_len)
 {
    if (index >=*list_len)
    {
        printf("刪除的位置超過連結串列最大長度\n");
        return FALSE;
    }
    pNode node_index = (pNode)malloc(sizeof(Node));
    if (node_index==NULL) return FALSE;

    if (index==0)//在表頭刪除
    {
        node_index=pl;
    } else
    {
        //遍歷到指定index 的位置的上一個位置
        node_index = TraverseList(pl,index-1);
    }
    //刪除節點
    node_index->next=node_index->next->next;
    //free(node_index->next);
    //node_index==NULL;
   // printf("node_index:data:%d\n",node_index->data);
    (*list_len)+=1;
    return TRUE;

 }
 BOOL ReversalList(pNode pl,int list_len)
 {
    pNode before_node=pl;
    if (list_len<=1)
    {
        printf("連結串列為空或長度為1\n");
        return TRUE;
    }

    before_node=before_node->next;
    pNode next_node=before_node->next;//記下第一個節點的下一個節點
    before_node->next=NULL;//讓第一個節點變成尾節點
    pNode current_node= next_node;//第一個節點處理完畢,下一個節點成為當前節點

    while(current_node!=NULL)
    {
        next_node=current_node->next;//記下下一個節點
        current_node->next=before_node;//當前節點指向上一個節點
        //為下一迴圈準備
        before_node=current_node;//上一個節點變成當前節點
        //printf("data:%d\n",before_node->data);
        current_node=next_node;//下一節點變成當前節點
    }
     pl->next=before_node;

    //TraverseList(pl,list_len);

    return TRUE;

 }
int main()
{
    //printf("Hello world!\n");
    int insert_num= 0;
    int index=0;
    int list_length =LIST_MAX_LEN;
    pNode pl=(pNode)malloc(sizeof(Node));

    InitNode(pl);
    printf("address pl=%d",pl);
   //建立連結串列
    CreateList(pl,list_length);

    //遍歷連結串列
    TraverseList(pl,list_length);

    //翻轉連結串列
    if(ReversalList(pl,list_length))
    {
        printf("翻轉成功\n");

        //遍歷連結串列
        TraverseList(pl,list_length);
    }

    //插入連結串列,並修改連結串列長度
    printf("請輸入插入的數字即位置:\n");
    scanf("%d%d",&insert_num,&index);
    if (InsertList(pl,insert_num,index,&list_length))
    {
       printf("插入成功\n");
       //遍歷連結串列
        TraverseList(pl,list_length);
    }

    //刪除連結串列,並修改連結串列長度
    printf("請輸入刪除的位置:\n");
    scanf("%d",&index);
    if (DeleteList(pl,index,&list_length))
    {
       printf("刪除成功\n");
       //遍歷連結串列
        TraverseList(pl,list_length);
    }


    return 0;
}

說下我碰到的問題:

在翻轉的時候,一開始我的程式是直接把形參裡的pl 帶入到while 迴圈裡去各種替換,然後發現打出的結果不對了:

 BOOL ReversalList(pNode pl,int list_len)
 {
    if (list_len<=1)
    {
        printf("連結串列為空或長度為1\n");
        return TRUE;
    }

    pl=pl->next;
    pNode next_node=pl->next;//記下第一個節點的下一個節點
    pl->next=NULL;//讓第一個節點變成尾節點
    pNode current_node= next_node;//第一個節點處理完畢,下一個節點成為當前節點

    while(current_node!=NULL)
    {
        next_node=current_node->next;//記下下一個節點
        current_node->next=pl;//當前節點指向上一個節點
        //為下一迴圈準備
        pl=current_node;//上一個節點變成當前節點
        printf("data:%d\n",pl->data);
        current_node=next_node;//下一節點變成當前節點
    }
    printf("address pl=%d",pl);
    //新建一個頭結點,並指向pl。
    pNode top=(pNode)malloc(sizeof(Node));
     if (top==NULL) return FALSE;
     top->next=pl;
     pl=top;
    printf("address pl=%d",pl);
    TraverseList(pl,list_len);

    return TRUE;

 }

結果如下:

結果可以看到,在 main 函式裡。,打出的pl的首地址跟在reversalList 函式裡打出的首地址一樣了,所以在呼叫函式裡能打出連結串列的所有值,而 main函式裡再去列印時,卻是從第9個數字的首地址開始列印的,當然就列印不全了。