zoukankan      html  css  js  c++  java
  • 带头结点单链表的翻转(递归)

    前言:

        单链表是基础的数据结构, 分为有头结点和无头结点, 无头结点使用起来比较麻烦, 下面是有头结点的单链表操作, 重点是在于有头结点的单链表翻转操作。

    代码:singlelist.c

    /*
        带头结点head的单链表
    
    */
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <assert.h>
    #include "list.h"
    
    NODE *head = NULL;
    
    /*
    翻转链表(递归方法)
    
    */
    NODE* reverse_list_recursion(NODE *pNode)
    {
        if(NULL == pNode || NULL == pNode->next)
            return pNode;
    
        NODE *newhead = reverse_list_recursion(pNode->next);
        if(pNode != head){
            pNode->next->next = pNode;
            pNode->next = NULL;
         return newhead; }
    else { pNode->next = newhead;
    return pNode; }
    } /* 尾插法插入节点到链表 1:首先需要找到尾结点, 它的标志就是next域为NULL 2:创建新结点初始化 3:尾结点的next域指向新结点 */ void tail_insert_node(NODE *head, int data) { NODE *tail = head; while(tail->next != NULL) tail = tail->next; NODE *p = (NODE *)calloc(1, sizeof(struct list)); p->data = data; p->next = NULL; tail->next = p; } /* 头插法插入结点到链表, 比尾插法简单, 不需要找到尾结点 1:创建新结点, 新结点的next指向头结点的next 2:头结点的next域指向新结点 */ void head_insert_node(NODE *head, int data) { NODE *p = (NODE *)calloc(1, sizeof(struct list)); p->data = data; p->next = head->next; head->next = p; } /* 尾插法初始化链表 */ void init_list_tail(NODE *head) { int array[5] = {1, 2, 3, 4, 5}; int i; assert(head); for(i=0; i<(sizeof array)/(sizeof array[0]); i++) { tail_insert_node(head, array[i]); } } /* 头插法初始化链表 */ void init_list_head(NODE *head) { int array[5] = {1, 2, 3, 4, 5}; int i; assert(head); for(i=0; i<(sizeof array)/(sizeof array[0]); i++) { head_insert_node(head, array[i]); } } /* 删除一个结点 */ void remove_list_node(NODE *head, int data) { if(NULL == head || NULL == head->next){ printf("Already empty list "); return; } NODE *pNode = head; NODE *ptr = NULL; while(pNode->next != NULL){ if(pNode->next->data != data) { pNode = pNode->next; continue; } else { ptr = pNode->next; pNode->next = pNode->next->next; free(ptr); return; } } printf("no this node in list "); } void print_list(NODE *head) { NODE *p = head->next; int i = 0; while(p){ printf("list[%d]:%d ", i++, p->data); p = p->next; } } int main(int argc, char const *argv[]) { head = (NODE *)calloc(1, sizeof(struct list)); init_list_tail(NULL); print_list(head); reverse_list_recursion(head); print_list(head); remove_list_node(head, 5); head = reverse_list_recursion(head); print_list(head); return 0; }

    list.h

    #ifndef __LIST_H__
    #define __LIST_H__
    
    typedef struct list {
        int data;
        struct list *next;
    }NODE;
    
    NODE* reverse_list_recursion(NODE *pNode);
    void tail_insert_node(NODE *head, int data);
    void head_insert_node(NODE *head, int data);
    void init_list_tail(NODE *head);
    void init_list_head(NODE *head);
    void print_list(NODE *head);
    
    #endif

     翻转单链表的函数:

    NODE* reverse_list_recursion(NODE *pNode)
    {
        if(NULL == pNode || NULL == pNode->next)
            return pNode;
    
        NODE *newhead = reverse_list_recursion(pNode->next);
        if(pNode != head){
            pNode->next->next = pNode;
            pNode->next = NULL;
       return newhead; }
    else { pNode->next = newhead;
    return pNode; }
    }

      使用了递归的思想, 可以把单链表看做只有左子树的树, 依次递归交换相邻两个树叶的指向。head是全局的头结点, 但是要判断一种特殊情况, 那就是pNode回归最后指向了head时(此时也是递归最后一次), 这时候就不要交换head和第一个结点的指向了, 只需要将head的next指向新的第一个结点newhead就可以了。

  • 相关阅读:
    第一次上机作业
    第一次java作业
    软件测试作业
    2021年的第一次作业
    Android作业----------------------购物车3.0
    Android作业----------------intent2.0
    Android作业----------------listview1.0
    Android-------------------数据存储
    Android--------------------跳转与数据传递
    Android----------PopWindow
  • 原文地址:https://www.cnblogs.com/Flychown/p/7851880.html
Copyright © 2011-2022 走看看