zoukankan      html  css  js  c++  java
  • 14--反转链表

    //
    //  main.cpp
    //  test_list_oper
    //
    //  Created by Hugo Cao  on 15/7/6.
    //  Copyright (c) 2015年 Hugo Cao . All rights reserved.
    //
    
    /*
    题目:反转链表
        伴随着大量的指针操作,3个指针,复杂度O(n).
    //反转链表,三个指针,遍历一次。
    lNode * secondReseverList(lNode *head)
    {
        //如果链表长度为0或者1,那么不需要翻转
        if (head == NULL || head->m_pNext == NULL)
        {
            cout << "无需翻转" << endl;
            return head;
        }
        
        lNode *p_head = NULL;   //返回的头节点
        lNode *p_Node = head;   //当前结点
        lNode *p_Prev = NULL;   //前一个节点
        
        while (p_Node != NULL)
        {
            //下一个节点,这是很关键的一步
            lNode *p_Next = p_Node->m_pNext;      
            if (p_Next == NULL)
            {
                p_head = p_Node;
            }
            
            p_Node->m_pNext = p_Prev;
            p_Prev = p_Node;
            p_Node = p_Next;
    
        }
        
        return p_head;
    }
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stack>
    #include <iostream>
    using namespace std;
    
    typedef struct ListNode
    {
        int m_nValue;
        struct ListNode *m_pNext;
    } lNode;
    
    
    //添加元素结点
    void listAddNode(lNode *head)
    {
        lNode *p = head, *p_Inter = NULL;
        
        if (!(p_Inter = ((lNode *)malloc(sizeof(lNode)))))
        {
            printf("the memery is don't create it
    ");
            return;
        }
        p_Inter->m_pNext = NULL;
        
        int data;
        printf("请输入数字:
    ");
        scanf("%d", &data);
        p_Inter->m_nValue = data;
        
        while (p->m_pNext != NULL)
        {
            p = p->m_pNext;
        }
        
        p->m_pNext = p_Inter;
        
    }
    
    
    //创建元素结点
    lNode* createList(lNode *head)
    {
        if (!(head = ((lNode *)malloc(sizeof(lNode)))))
        {
            printf("the memery is don't create it
    ");
            return NULL;
        }
        head->m_pNext = NULL;
        int data;
        printf("请输入数字:
    ");
        scanf("%d", &data);
        head->m_nValue = data;
        
        
        lNode *p = head;
        char X_cin = 'Y';
        while (true)
        {
            printf("是否继续添加:N/n 
    ");
            cin >> X_cin;
            
            if (X_cin == 'y' || X_cin == 'Y')
            {
                ;
            }
            else if (X_cin == 'N' || X_cin == 'n')
            {
                return head;
            }
            else
            {
                ;
            }
            
            listAddNode(p);
        }
        
    }
    
    
    //显示列表
    void showList(lNode *head)
    {
        if (NULL == head)
        {
            cout << "list is empty 
    " << endl;
            return;
        }
        
        lNode *p = head;
        
        while (p != NULL)
        {
            printf("%d
    ", p->m_nValue);
            p = p->m_pNext;
        }
        
    }
    
    
    //翻转链表
    void reversePut(lNode *point)
    {
        stack <int> stack_rev;
        lNode *p = point;
        
        while (p != NULL)
        {
            stack_rev.push(p->m_nValue);
            p = p->m_pNext;
        }
        
        cout << "翻转以后的输出" << endl;
        while (!stack_rev.empty())
        {
            cout << stack_rev.top() << endl;
            stack_rev.pop();
        }
    }
    
    
    //输出倒数第K个元素节点,遍历所有节点型。
    void firstPrintNode(lNode *head, int kNum)
    {
        int length = 0;
        lNode *p = head;
        
        while (p != NULL) {
            p = p->m_pNext;
            length++;
        }
        if (length < kNum)
        {
            cout << "链表长度为:" << length << ", 而遍历的节点位置是: "<< kNum << endl;
            return;
        }
        cout << "链表长度为:" << length;
        p = head;
        while (length != kNum) {
            length--;
            p =  p->m_pNext;
        }
        
        cout << "  输出倒数第K个元素节点: " << p->m_nValue << endl;
    }
    
    //输出第K个结点,第二种方式,两个指针
    void secondPrintNode(lNode *head, int kNum)
    {
        lNode *p1 = head;
        lNode *p2 = head;
        int length = kNum;
        
        while (p1 != NULL) {
            p1 = p1->m_pNext;
            length--;
            if (length < 0)
                p2 = p2->m_pNext;
        }
        
        cout << "  输出倒数第K个元素节点: " << p2->m_nValue << endl;
    }
    
    //反转链表,三个指针,遍历一次。
    lNode * secondReseverList(lNode *head)
    {
        //如果链表长度为0或者1,那么不需要翻转
        if (head == NULL || head->m_pNext == NULL)
        {
            cout << "无需翻转" << endl;
            return head;
        }
        
        lNode *p_head = NULL;   //返回的头节点
        lNode *p_Node = head;   //当前结点
        lNode *p_Prev = NULL;   //前一个节点
        
        while (p_Node != NULL)
        {
            lNode *p_Next = p_Node->m_pNext;      //下一个节点
            if (p_Next == NULL)
            {
                p_head = p_Node;
            }
            
            p_Node->m_pNext = p_Prev;
            p_Prev = p_Node;
            p_Node = p_Next;
    
        }
        
        return p_head;
    }
    
    
    int main()
    {
        lNode *head = NULL;
        
        head = createList(head);
        //showList(head);
        //翻转链表,用栈实现,
        //reversePut(head);
        //输出倒数第K个元素
        //secondPrintNode(head, 3);
        //secondReseverList(head);
        head = secondReseverList(head);
        showList(head);
        return 0;
    }
  • 相关阅读:
    Project Chameleon Work In Progress 14
    All about Project Chameleon
    网页中图片连续滚动代码 (转)
    一点感言
    一些常用javascript代码(转)
    asp.net(c#)的一个非常非常奇怪的问题
    用javascript拦截a标签的超链接执行
    asp.net中用TreeView控件实现无限分级的好办法
    windows7 安装ez usb基本驱动
    管道编程
  • 原文地址:https://www.cnblogs.com/hgonlywj/p/4842560.html
Copyright © 2011-2022 走看看