链表翻转

来源:互联网 发布:spss软件 教学大纲 编辑:程序博客网 时间:2024/06/05 14:21

问题
链表翻转。给出一个链表和一个数k,比如,链表为1→2→3→4→5→6,k=2,则翻转后2→1→6→5→4→3,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→6→5,用程序实现。
在之前我们肯定都写过链表的翻转程序:

NodePtr ReverseList(NodePtr head){cout << "reverse list" << endl;//若只有头或者只有一个节点,则不用翻转if(head->next == NULL || head->next->next == NULL)    return head;NodePtr p, q, r;p = head->next;q = p->next;//翻转过程while(q){    r = q->next;    q->next = p;    p = q;    q = r;} //翻转过后改变头指针head->next = p;return head;} 

本题与全翻转链表有很大的相似之处,当然也有很大的不同之处。相似之处在于翻转的过程同事相同的,而不同之处则在于本题中包含两个部分的翻转,并且在头指针的指向以及第一个翻转过后还有一些操作需要处理。大致过程如下草图所示

该图中黑色表示链表的最初始状态,红色表示翻转的第一部分,绿色表示第二部分的翻转。
该实例表示的是k=2时的翻转,第一部分的翻转我们需要注意的问题是:

1.准确的定位。在链表中有时候会把人弄糊涂,因此一定要准确的定位到第二个节点,然后再开始翻转。

2.翻转过后头结点的指向。在本例中第一部分翻转过后一定要将head节点指向第一部分翻转的起始节点,即第二个节点。

3.第一部分翻转过后的最后一个节点的指向也一定要搞清楚。在本例中翻转过后第一个节点的下一个指向一定要指向节点3.

第一部分翻转完成过后我们开始第二部分的翻转。第二部分的翻转相对而言要简单很多,只需要注意翻转过后,一定要将第一部分翻转过后的最后一个节点的next指向最后一个节点。程序代码如下所示(这个程序还是有一点问题的,如果是全翻转的话会有问题,但是这只是增加判断的问题,主要思路都是对的)

bool ReverseLink(LinkList link, int k){//若只有头或者只有一个节点,则不用翻转if(link->next == NULL || link->next->next == NULL)    return false;LinkList p, q, r, firstNode;int count = 1;firstNode = link->next;p = link->next;     //头结点 q = p->next;        //第二个节点//前k个节点的翻转 while(count<k && q){    r = q->next;    q->next= p;    p = q;    q = r;    count++;} firstNode->next = r;link->next = p;//后面节点的翻转p = firstNode->next;q = p->next; while(q){    r = q->next;    q->next = p;    p = q;    q = r;}firstNode->next->next = NULL;firstNode->next = p;return true;    }

下面是整体的代码,可以直接运行,已经在机器上测试过:

#include<iostream>using namespace std;typedef int ElemType;struct Link{    ElemType data;    struct Link *next;};typedef Link *LinkList;bool InitLink(LinkList *link){    *link = (LinkList)malloc(sizeof(Link));    if(!(*link))        return false;    (*link)->next = NULL;    return true;}bool InsertList(LinkList *link, ElemType elem){    if(NULL == *link)        return false;    LinkList p, q;    p = *link;    q = (LinkList)malloc(sizeof(Link));    q->data = elem;    q->next = NULL;    while(NULL != p->next)        p = p->next;    p->next = q;    return true;}bool ReverseLink(LinkList link, int k){    //若只有头或者只有一个节点,则不用翻转    if(link->next == NULL || link->next->next == NULL)        return false;    LinkList p, q, r, firstNode;    int count = 1;    firstNode = link->next;    p = link->next;     //头结点     q = p->next;        //第二个节点    //前k个节点的翻转     while(count<k && q){        r = q->next;        q->next= p;        p = q;        q = r;        count++;    }     firstNode->next = r;    link->next = p;    //后面节点的翻转    p = firstNode->next;    q = p->next;     while(q){        r = q->next;        q->next = p;        p = q;        q = r;    }    firstNode->next->next = NULL;    firstNode->next = p;    return true;    }void printLink(LinkList link){    LinkList p;    p = link;    while(NULL != p->next ){        cout << p->next->data << "---> " ;        p = p->next;    }    cout << endl;}int main(){    LinkList link;    InitLink(&link);    InsertList(&link, 1);    InsertList(&link, 2);    InsertList(&link, 3);    InsertList(&link, 4);    InsertList(&link, 5);    InsertList(&link, 6);    printLink(link);    ReverseLink(link, 5);    printLink(link);    return 0;}
0 0
原创粉丝点击