Reversing Linked List

本文记录了一段C++代码,用于解决给定链表按顺序入栈,然后每次弹出m个元素并反转的问题。作者在实现过程中遇到了链表排序和反转的挑战,包括使用栈实现链表反转,以及遇到的时间复杂度过高的问题。文章还讨论了代码中的一些细节,如如何处理链表节点和数据结构。
摘要由CSDN通过智能技术生成

题目要求

在这里插入图片描述
在这里插入图片描述
输入:

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

代码

#include <iostream>    
#include <stack>
using namespace std;
    
// 1051 Pop Sequence(25 point(s))
int main(void){    
    const int N = 1005;
    int arr[N]={0};
    int m,n,k;
    cin>>m>>n>>k;
     
    for(int j=0;j<k;++j){   // k line
        for(int i=1;i<=n;++i){  
            cin>>arr[i]; 
        }
         
        stack<int> st;
        while(!st.empty()){ // empty stack
            st.pop();
        }
 
        bool flag = true; 
        int num = 1;
        for(int i=1;i<=n;++i){
            st.push(i);     // order
            if(st.size()>m){// the maximum capacity 
                flag = false;
                break;
            }
            while(st.empty()==false && st.top()==arr[num]){
                st.pop();
                ++num;
            }
        }
         
        if(flag && st.empty()){
            cout<<"YES"<<endl;
        }else{ 
            cout<<"NO"<<endl;
        }
    }
 
    return 0;
} // jinzheng 2018.9.3 14:14

复习感悟

1.对c++的map还是不熟悉,所以对输入按顺序整理链表的时候,采用的是很笨的遍历方法,复习写的方法在PTA测试,也是对N最大的时候运行超时,猜测主要是排序的时候时间太长了
2、这其实比普通的反转链表要难一点,因为可能涉及到多次翻转,在第二次写的时候也对reverse函数返回应该返回什么,因为reverse函数的进入是一个带头结点的链表,当进行第一次反转后,需要进行第二次翻转,怎么使进入的链表带头结点,第二次的方法是在看了第一次写的方法后自己想出来的,虽然复杂一点,但感觉能更好理解,语言描述就是:在进行第二次翻转之前,让链表从头到需要翻转的后序链表的前一个,通过temp=temp->next来做到,难点在于需要进行多少次。
3.第二次写对地址也设置的int型,但是发现会省略0,才改成string
reverse函数

LNode reverse(LNode List, int k) {
    LNode newL = List->next;//new是关键字,不能命名为new
    LNode old = List->next->next;
    LNode temp;
    int count = 1;
    while (count < k) {
        temp = old->next;
        old->next = newL;
        newL = old;
        old = temp;
        count++;
    }
    List->next->next = old;//需要先修改next->next,先修改next的话修改next->next就会出错
    List->next = newL;
    return List;
}

排序函数(时间复杂度高,多使用map)

LNode sort(LNode head) {
    LNode L = new Node;
    L->next_address = head->address;
    L->next = NULL;
    LNode L_last = L;
    LNode newnode;
    LNode temp = head->next;
    while (L_last->next_address != "-1") {//错写成address,所以出不来循环
        temp = head->next;
        while (temp) {
            if (temp->address == L_last->next_address) {
                newnode = new Node;//忘记初始化
                newnode->address = temp->address;
                newnode->data = temp->data;
                newnode->next_address = temp->next_address;
                newnode->next = NULL;
                L_last->next = newnode;
                L_last = L_last->next;
            }
            temp = temp->next;
        }
    }
    return L;
}

所有程序:

#include<iostream>
#include<string>
using namespace std;
struct Node {
    string address;
    int data;
    string next_address;
    Node* next;
};
typedef Node* LNode;
LNode sort(LNode head) {
    LNode L = new Node;
    L->next_address = head->address;
    L->next = NULL;
    LNode L_last = L;
    LNode newnode;
    LNode temp = head->next;
    while (L_last->next_address != "-1") {//错写成address,所以出不来循环
        temp = head->next;
        while (temp) {
            if (temp->address == L_last->next_address) {
                newnode = new Node;//忘记初始化
                newnode->address = temp->address;
                newnode->data = temp->data;
                newnode->next_address = temp->next_address;
                newnode->next = NULL;
                L_last->next = newnode;
                L_last = L_last->next;
            }
            temp = temp->next;
        }
    }
    return L;
}
LNode reverse(LNode List, int k) {
    LNode newL = List->next;//new是关键字,不能命名为new
    LNode old = List->next->next;
    LNode temp;
    int count = 1;
    while (count < k) {
        temp = old->next;
        old->next = newL;
        newL = old;
        old = temp;
        count++;
    }
    List->next->next = old;//需要先修改next->next,先修改next的话修改next->next就会出错
    List->next = newL;
    return List;
}
void print(LNode list) {
    LNode l = list->next;
    while (l->next) {
        l->next_address = l->next->address;
        l = l->next;
    }
    if (!l->next)
        l->next_address = "-1";
    l = list->next;
    while (l) {
        cout << l->address << " " << l->data << " " << l->next_address << endl;
        l = l->next;
    }
}
int main() {
    string firstaddress;
    int N, K;
    cin >> firstaddress >> N >> K;
    LNode head = new Node;
    head->address = firstaddress;
    head->next = NULL;
    LNode last = head;
    LNode newnode;
    for (int i = 0; i < N; i++) {
        newnode = new Node;
        cin >> newnode->address >> newnode->data >> newnode->next_address;
        newnode->next = NULL;
        last->next = newnode;
        last = last->next;
    }
    LNode list = sort(head);
    N = 0;//因为有可能有多余的结点,所以需要重新计算排序后有多少个结点
    LNode list_n = list->next;
    while (list_n) {
        N++;
        list_n = list_n->next;
    }
    int cnt = N / K;
    if (cnt<=1) {
        list = reverse(list, K);
    }
    else {
        int i = 0;
        LNode temp;
        while (i < cnt) {
            temp = list;
            for (int j = 0; j < i * K; j++) {
                temp = temp->next;
            }
            reverse(temp, K);//不要加list=,因为后期返回的不是list
            i++;
        }
    }
    print(list);

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值