反轉鏈表

【題目】node

定義一個函數。輸入一個鏈表的頭結點,反轉該鏈表並輸出反轉後的鏈表的頭結點。markdown


【分析】函數

單鏈表的延伸題,基本單鏈表如前面博客裏所述方法建立,對於反轉鏈表。實現的過程就是遍歷一個結點。記錄他的前一節點,讓現在的結點的下一指針指向前一結點,但是爲了保證可以繼續遍歷原下一節點,不形成斷節,還需要注意保證結點的原下一個節點也被保存。同一時候要注意到檢查到最後一個結點就是反轉鏈表的頭結點。基本步驟例如如下所看到的:ui

這裏寫圖片描寫敘述

先看pNode是否爲空,爲空說明遍歷完成(或者鏈表原本就是空的,但是不影響),不然循環下一過程:
1. 先把當前節點的下一節點存下來,推斷當前節點是否是尾結點。尾結點就是反轉鏈表頭結點。不然,進入第2步。
2. 通過第1步,保證了待會可以沿着原鏈表繼續遍歷,因此放心的進行這步。讓當前節點指向前一節點;
3. 進入第3步說明當前節點和前一節點關係已經反轉完,因此當前節點將做爲原鏈表中下一節點中的前一節點。spa


【測試代碼】指針

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

typedef int data_type;

typedef struct Node node_t;// 給struct Node取個別名node_t
typedef struct Node * node_ptr;//給struct Node*取個別名node_ptr

typedef struct Node
{
    data_type data;
    struct Node *node_next;//node_next是一個指向結構的指針。告訴指針要指向的地址就要付給它一個結構類型地址
};

//鏈表初始化
node_t * init()
{
    node_ptr p;
    p = (node_t *)malloc(sizeof(node_t));
    p->node_next = NULL;
    return p;
}
//在鏈表後面插入結點
node_t *insert_back(node_ptr p , data_type data)
{


    node_ptr pnew = (node_t *)malloc(sizeof(node_t));
    pnew ->node_next = NULL;
    pnew ->data = data;

    p->node_next = pnew;

    return pnew;
}


node_t * reverse(node_ptr p)
{
    node_ptr pReverseHead = NULL;
    node_ptr pNode = p;
    node_ptr pre = NULL;

    while(pNode != NULL)
    {
        node_ptr pnext = pNode->node_next;
        if(pNode->node_next == NULL)
            pReverseHead = pNode;

        pNode->node_next = pre;

        pre = pNode;
        pNode = pnext;
    }

    return pReverseHead;

}
//正常打印
void print(node_ptr p)
{
    if(!p)
    {
            printf("no data, you think too much");
            return ;
    }
    node_ptr list = p;
    while(list->node_next != NULL)
    {
        printf("%d ", list->data);
        list = list->node_next;
    }
    printf("%d ",list->data);
    printf("\n");

}



void main()
{
    node_ptr pnode, list;
    pnode = init();
    list = pnode;

    pnode = insert_back(pnode, 1);
    pnode = insert_back(pnode, 2);
    pnode = insert_back(pnode, 3);
    pnode = insert_back(pnode, 4);
    pnode = insert_back(pnode, 5);
    pnode = insert_back(pnode, 6);
    printf("正常單鏈表順序爲:");
    print(list->node_next);
    printf("頭結點元素爲:%d\n", list->node_next->data);
    printf("\n");
    node_t *reverse_list_head= reverse(list->node_next);
    printf("反轉單鏈表順序爲:");
    print(reverse_list_head);
    printf("頭結點元素爲:%d\n",reverse_list_head->data);
    printf("\n");

}

【輸出】
這裏寫圖片描寫敘述code


【遞歸實現】遞歸

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

typedef int data_type;

typedef struct Node node_t;// 給struct Node取個別名node_t
typedef struct Node * node_ptr;//給struct Node*取個別名node_ptr

typedef struct Node
{
    data_type data;
    struct Node *node_next;//node_next是一個指向結構的指針。告訴指針要指向的地址就要付給它一個結構類型地址
};

//鏈表初始化
node_t * init()
{
    node_ptr p;
    p = (node_t *)malloc(sizeof(node_t));
    p->node_next = NULL;
    return p;
}
//在鏈表後面插入結點
node_t *insert_back(node_ptr p , data_type data)
{


    node_ptr pnew = (node_t *)malloc(sizeof(node_t));
    pnew ->node_next = NULL;
    pnew ->data = data;

    p->node_next = pnew;

    return pnew;
}

//遞歸反轉單鏈表
void reverse_rec(node_ptr proot, node_t **head)
{
    if(proot == NULL)
        return ;
    if(proot->node_next == NULL)
    {
        *head = proot;
        return ;
    }
    reverse_rec(proot->node_next, head);

    proot->node_next ->node_next= proot;
    proot->node_next = NULL;    
}

//正常打印
void print(node_ptr p)
{
    if(!p)
    {
            printf("no data, you think too much");
            return ;
    }
    node_ptr list = p;
    while(list->node_next != NULL)
    {
        printf("%d ", list->data);
        list = list->node_next;
    }
    printf("%d ",list->data);
    printf("\n");

}



void main()
{
    node_ptr pnode, list;
    pnode = init();
    list = pnode;

    pnode = insert_back(pnode, 1);
    pnode = insert_back(pnode, 2);
    pnode = insert_back(pnode, 3);
    pnode = insert_back(pnode, 4);
    pnode = insert_back(pnode, 5);
    pnode = insert_back(pnode, 6);
    printf("正常單鏈表順序爲:");
    print(list->node_next);
    printf("頭結點元素爲:%d\n", list->node_next->data);
    printf("\n");
    reverse_rec(list->node_next, &list);
    printf("反轉單鏈表順序爲:");
    print(list);
    printf("頭結點元素爲:%d\n",list->data);
    printf("\n");

}
相關文章
相關標籤/搜索