【链表】链表翻转,合并,以及倒数第k个数

链表的翻转

1. 代码中指明了链表的定义,以及初始化,初始化使用尾插法实现。

2. 链表的翻转采用三种方式,分别是递归,栈,以及对链表逆序后,再输出

代码如下:

#include <iostream>
#include<stack>
using namespace std;
typedef struct Node{
    int data;
    Node* next;

}Node;
//尾部添加
Node* tailAdd(Node* head, int e){
    Node* t = new Node;
    t->data = e;
    t->next = NULL;
    if(head == NULL){
        head = t;
    }else if(head ->next == NULL){
        head->next = t;
    }else{
        Node* p = head->next;
        while(p->next != NULL){
            p = p->next;
        }
        p->next = t;
    }
    return head;
}
//顺序输出
void print(Node* head){
    Node* p = head;
    while(p!=NULL){
        cout<<p->data<<" ";
        p = p->next;
    }
    cout<<endl;
}
//递归 逆序输出
void dg(Node *head){
    Node* p = head;
    if(p!=NULL){
        dg(p->next);
        cout<<p->data<<" ";
    }
}
//栈,实现逆序
void reversePrint(Node* head){
    stack<int > s;
    while(head!=NULL){
        s.push(head->data);
        head = head->next;
    }
    while(!s.empty()){
        cout << s.top() << " ";
        s.pop();
    }
    cout<<endl;
}

//还有一种,链表逆序后输出
Node* revers(Node* head){
    if(head == NULL || head->next == NULL){
        return head;
    }
    Node* p1 = head;   //p1保存翻转后的链表
    Node* p2 = head->next;  //p2保存原始链表
    Node* p3 = NULL;    //临时存储结点
    head->next = NULL;  //pHead的第一个结点是尾结点,尾结点下一个结点是NULL;
    while(p2!=NULL){      // p2为空,停止循环
        p3 = p2;    //  p2指向的当前结点,存到临时结点
        p2 = p2->next;  //p2向后指一个结点,为下次循环做准备
        p3->next = p1;   //p3指向已经翻转的链表p1,实现链表翻转
        p1 = p3;        //p3重新赋值给p1
    }
    head = p1;   //把p1赋值给头结点head。
    return head;
}

int main()
{
    Node* head = NULL;
    for(int i=1;i<=5;i++){
        head = tailAdd(head,i); //尾部添加数据

    }
    print(head); //顺序输出链表
    dg(head);  //翻转递归输出 
    reversePrint(head);  //栈翻转输出
    
    head = revers(head);  //先将链表逆序返回
    print(head);          //再把逆序的链表输出
    return 0;
}

链表合并

Node* Merge(Node* pHead1, Node* pHead2)
    {
        Node* p = new Node;
        p->data = 0;
        p->next = NULL;
        if(pHead1==NULL && pHead2==NULL){
            p =NULL;
            return p;
        }else if(pHead1==NULL){
            p = pHead2;
            return p;
        }else if(pHead2 == NULL){
            p = pHead1;
            return p;
        }else{
            Node* p1=pHead1;
            Node* p2=pHead2;
            if(pHead1->data < pHead2->data){
                p = pHead1;
                p1 = p1->next;
            }else{
                 p = pHead2;
                p2 = p2->next;
            }
            pHead1 = p;
            while(p1!=NULL && p2!=NULL){
                if(p1->data < p2->data){
                    p->next = p1;
                    p1 = p1->next;
                    p = p->next;
                }else{
                    p->next = p2;
                    p2 = p2->next;
                    p = p->next;
                }
            }
            if(p1!=NULL){
                p->next = p1;
            }else if(p2!=NULL){
                p->next = p2;
            }else{
                p->next = NULL;
            }
            return pHead1;
        }

    }

链表中倒数第k个结点

有两种方法:

1. 先遍历链表,算出链表结点数count,第二次直接遍历到第count-k个结点。但是要注意,可能链表结点数cout小于k,此时要返回NULL。这一条件要先判断。

代码:

Node* FindKthToTail(Node* pListHead, unsigned int k) { //k表示倒数第k个结点
       int count = 1;
        Node* p =pListHead;
        if(pListHead==NULL || k==0){ 
            count=0;
        }else{
            while(p->next != NULL){   //先遍历链表
                count++;
                p = p->next;
            }
        }
        Node* r =new Node;
        r = NULL;
        if(count<k || count==0){
            r =NULL;
            return r;
        }else{
            p = pListHead;
            for(int i=0;i<count-k;i++){   //遍历到链表count-k个结点
                p = p->next;
            }
            r = p;
            return r;
        }

    }

2. 可以用两个指针,第一个指针遍历到第k个结点的时候,第二个指针再走到第一个结点,两个指针之间始终保持k-1的距离,当第一个指针的next==NULL,第二个指针对应的位置,就是倒数第k个结点。

Node* FindKthToTail(Node* pListHead, unsigned int k) {

        Node* first = pListHead;
        Node* second = pListHead;
        Node* r =new Node;
        int count = 1;
        if(pListHead==NULL || k==0){
            r = NULL;
            return r;
        }else{
            while(first->next != NULL){
                count++;
                if(count>=k+1){
                    second = second->next;
                }
                first = first->next;
            }
            if(count<k){
                r = NULL;
                return r;
            }else{
                r = second;
                return r;
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/csdn_chuxuezhe/article/details/82695754