翻转链表

来源:互联网 发布:腾达路由器mac怎么改 编辑:程序博客网 时间:2024/05/18 00:47

题目描述:
给定一个常数K以及一个单链表L,请编写程序将L中每K个结点反转。例如:给定L为1→2→3→4→5→6,K为3,则输出应该为3→2→1→6→5→4;如果K为4,则输出应该为4→3→2→1→5→6,即最后不到K个元素不反转。

输入格式:

每个输入包含1个测试用例.每个测试用例给出两个正整数N和K,其中N为节点总个数,第二行依次给出N个正整数,分别为链表中的键值.

输出格式:

分行输出结果,每个结果一行.

要求:

以链表形式实现.

注:我的编译环境为visual studio 2017 community.

思路:

我这里采用的是建立一个新的链表的方法,按照要求的顺序来复制原链表的键值.
假设N=6,K=4.
这里写图片描述

  1. Tmp初始化为L.Next
  2. Head初始化为Tmp,然后在计数器下,运行三次Tmp=Tmp.Next,此时Tmp先后指向了K(4)个节点(包括初始化时指向的节点).将Tmp此时指向的节点的键值压入New的栈中,Tmp后移一个节点(即节点5).
  3. 接下来使用循环将剩余的K-1个(即3个)键值压入栈中: 每次循环开始时Rail初始化为Head,再后移一定的节点(依将要压入栈中的节点而定,节点3Rail要后移2个节点,节点2Rail要后移1个节点,以此类推),到达指定位置后,将键值压入栈中.
  4. 重复步骤2,3直到剩余的节点数不足以翻转一次.

代码:

#include "stdafx.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <time.h>#include <iomanip>#include <math.h>using namespace std;struct LinkedListNode{    int Element;    LinkedListNode* Next;};typedef LinkedListNode* LinkedList;class Stack{private:    int NodeNumber;public:    Stack()    {        NodeNumber = 0;    }    LinkedList Initialize()    {        LinkedList L = new LinkedListNode;        L->Element = 0;        L->Next = NULL;        return L;    }    bool IsEmpty(LinkedList L)    {        return L->Next == NULL;    }    void Push(LinkedList L,int X)    {        LinkedList Tmp = L;        while (Tmp->Next != NULL)            Tmp = Tmp->Next;        LinkedList Node = new LinkedListNode;        Node->Element = X;        Node->Next = NULL;        Tmp->Next = Node;        NodeNumber++;    }    int Pop(LinkedList L)    {        if (IsEmpty(L))        {            cout << "Empty Stack!" << endl;            return 0;        }        LinkedList End=L->Next;        while (End->Next != NULL)            End = End->Next;        LinkedList Pre = L;        while (Pre->Next->Next != NULL)            Pre = Pre->Next;        Pre->Next = NULL;        int Ret = End->Element;        delete End;        NodeNumber--;        return Ret;    }    int GetNodeNumber()    {        return NodeNumber;    }    void Show(LinkedList L)    {        if (IsEmpty(L))        {            cout << "Empty Stack!" << endl;            return ;        }        LinkedList P = L->Next;        while (P != NULL)        {            cout << P->Element <<endl;            P = P->Next;        }    }    LinkedList Reverse(LinkedList L,int K)//K>=1且K不大于栈中节点数    {        if (IsEmpty(L))        {            cout << "Empty Stack!" << endl;            return L;        }        if (K == 1)//如果K为1,则直接返回L            return L;        LinkedList New = Initialize();        LinkedList Tmp = L->Next,P=New;        LinkedList Head, Rail;        while (1)        {            Head = Tmp;            for (int i = 0; i < K-1; i++)            {                if (Tmp == NULL)//如果NK的倍数,则返回New                    return New;                else if (Tmp->Next != NULL)                    Tmp = Tmp->Next;                else//如果N不是K的倍数,则继续把链表最后面不到K个节点复制到链表New中,再返回New                {                    while (Head != NULL)                    {                        Push(New, Head->Element);                        Head = Head->Next;                    }                    return New;                }            }            Push(New, Tmp->Element);            Tmp = Tmp->Next;            for (int i = K-1; i >0; i--)            {                Rail = Head;                for (int j = 0; j < i - 1; j++)                    Rail = Rail->Next;                Push(New, Rail->Element);            }        }    }};int main(){    int N, K;    cin >> N >> K;    int *arr = new int[N];    for (int i = 0; i < N; i++)        cin >> arr[i];    Stack LL;    LinkedList L = LL.Initialize();    for (int i = 0; i < N; i++)        LL.Push(L,arr[i]);    LinkedList New = LL.Reverse(L, K);    LL.Show(New);    return 0;}
原创粉丝点击