【CODE】CoderPad——单链表

目录

1.单链表反转

2.不遍历链表删除非尾节点

3.遍历一次,找到中间节点

4.遍历一次,找到倒数第 k 个结点(k从1开始)

5.遍历一次,删除倒数第 k 个结点(k从1开始),不能用替换删除法

6.合并两个有序链表

7.判断链表是否有环,求环的长度和入口点

8.判断两个不带环的链表是否相交,若相交,求交点。

9.可能带环的两个链表的交点

10.约瑟夫环

11.冒泡排序用单链表实现


1.单链表反转

#include<iostream>
#include<stdlib.h>
using namespace std;
typedef struct ListNode{
  int value;
  ListNode *next;
}ListNode;
void print(ListNode *head){
  while(head!=NULL){
    cout<<head->value<<" ";
    head=head->next;
  }
  return;
}
ListNode* reverse(ListNode* head){
  ListNode* tmp=head;
  head=NULL;
  while(tmp){
    ListNode* tmpp=tmp;
    tmp=tmp->next;
    tmpp->next=head;
    head = tmpp;
  }
  return head;
}
int main(){
  ListNode *head=(ListNode*)malloc(sizeof(ListNode));
  ListNode *HEAD = (ListNode *)malloc(sizeof(ListNode));
  int n;
  cin>>n;
  for(int i=0;i<n;i++){
    ListNode *headd=(ListNode*)malloc(sizeof(ListNode));
    int value;
    cin>>value;
    headd->value=value;
    headd->next = NULL;
    if(i!=0){
        head->next=headd;
    }else{
        HEAD = headd;
    }
    head=headd;
  }
  HEAD=reverse(HEAD);
  print(HEAD);
  system("pause");
  return 0;
}

2.不遍历链表删除非尾节点

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
}ListNode;
void DelNotTail(ListNode *pDel){
    ListNode *pDelnext = pDel->next;
    pDel->value = pDelnext->value;
    pDel->next = pDelnext->next;
    free(pDelnext);
    return;
}
void print(ListNode *head){
    while(head!=NULL){
        cout << head->value<<" ";
        head = head->next;
    }
    return;
}
ListNode* initList(int arr[],ListNode *head,int n){
    ListNode *HEAD =head;
    for (int i = 0; i < n;i++){
        ListNode *headd = (ListNode*)malloc(sizeof(ListNode));
        head->value = arr[i];
        if(i!=n-1){
            head->next = headd;
            head = headd;
        }else
            head->next = NULL;
    }//初始化的时候,尾节点->next=NULL,而不是一个空节点。
    return HEAD;
}
int main(){
    int arr[7] = { 1, 2, 3, 4, 5, 6, 7 };
    ListNode *head = (ListNode*)malloc(sizeof(ListNode));
    ListNode *HEAD=initList(arr, head, 7);
    while(head){
        if(head->value==4){
            DelNotTail(head);
            break;
        }else head = head->next;
    }
    print(HEAD);
    system("pause");
    return 0;
}

3.遍历一次,找到中间节点

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
}ListNode;
ListNode* initList(int a[],ListNode *head,int n){
    ListNode *HEAD = head;
    for (int i = 0; i < n;i++){
        ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
        head->value = a[i];
        if(i!=n-1){
            head->next = headd;
            head = headd;
        }else head->next = NULL;
    }
    return HEAD;
}
ListNode* FindMid(ListNode* head){
    ListNode *one =head;
    ListNode *two =head;
    while(two->next!=NULL){
        one = one->next;
        two = two->next;
        if(two->next!=NULL) two = two->next;
        else break;
    }
    return one;
}
int main(){
    int a[9] = {1, 2, 3, 4, 5, 6, 7,9};
    ListNode *head = (ListNode *)malloc(sizeof(ListNode));
    head = initList(a, head, 9);
    head = FindMid(head);
    cout << head->value;
    system("pause");
    return 0;
}

4.遍历一次,找到倒数第 k 个结点(k从1开始)

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
} ListNode;
ListNode* findK(ListNode* head,int k){
    ListNode *one = head;
    ListNode *two = head;
    for (int i = 0; i < k;i++){
        two = two->next;
    }
    while(two){
        one = one->next;
        two = two->next;
    }
    return one;
}
int main(){
    int n;
    cin >> n;
    ListNode *head = (ListNode *)malloc(sizeof(ListNode));
    ListNode *HEAD = head;
    for (int i = 0; i < n;i++){
        ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
        int value;
        cin >> value;
        head->value = value;
        if(i!=n-1){
            head->next = headd;
            head = headd;
        }else
            head->next = NULL;
    }
    ListNode *tmp = findK(HEAD, 3);
    cout << tmp->value << endl;
    system("pause");
    return 0;
}

5.遍历一次,删除倒数第 k 个结点(k从1开始),不能用替换删除法

找到倒数第k+1个节点,其next就是倒数第k个节点。

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
} ListNode;
ListNode* findKDel(ListNode *head,int k){
    ListNode *one = head;
    ListNode *two = head;
    for (int i = 0; i < k + 1;i++){
        two = two->next;
    }
    while(two){
        one = one->next;
        two = two->next;
    }
    ListNode *tmp = one->next;
    one->next = tmp->next;
    free(tmp);
    return head;
}
void print(ListNode* head){
    while(head){
        cout << head->value << " ";
        head = head->next;
    }
    return;
}
int main(){
    int n,k;
    cin >> n>>k;
    ListNode *head = (ListNode *)malloc(sizeof(ListNode));
    ListNode *HEAD = head;
    for (int i = 0; i < n;i++){
        int value;
        cin >> value;
        ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
        head->value = value;
        if(i!=n-1){
            head->next = headd;
            head = headd;
        }else
            head->next = NULL;
    }
    if(n==k){
        head = HEAD->next;
        free(HEAD);
        HEAD = head;
    }
    else
        findKDel(HEAD, k);
    print(HEAD);
    system("pause");
    return 0;
}

6.合并两个有序链表

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
} ListNode;
ListNode *addList(ListNode *headA,ListNode *headB){
    ListNode *head = NULL;
    if(headA==NULL) return headB;
    if(headB==NULL) return headA;
    if(headA->value<headB->value){
        head=headA;
        headA = headA->next;
    }
    else{
        head = headB;
        headB = headB->next;
    }
    ListNode *HEAD = head;
    while (headA && headB) {
        if (headA->value < headB->value) {
            head->next= headA;
            head = head->next;
            headA = headA->next;
        }
        else {
            head->next= headB;
            head = head->next;
            headB = headB->next;
        }
    }
    if(headA) head->next=headA;
    if(headB) head->next=headB;
    return HEAD;
}
void print(ListNode *head){
    while(head){
        cout << head->value << " ";
        head = head->next;
    }
    return;
}
int main(){
    int a[] = {1, 3, 5, 7};
    int b[] = {2, 5};
    ListNode *A = (ListNode *)malloc(sizeof(ListNode));
    ListNode *B = (ListNode *)malloc(sizeof(ListNode));
    ListNode *headA = A, *headB = B;
    for (int i = 0; i < 4;i++){
        ListNode *tmp = (ListNode *)malloc(sizeof(ListNode));
        A->value = a[i];
        if(i!=3){
            A->next = tmp;
            A = tmp;
        }
        else if(i==0) headA = A;
        else A->next = NULL;
    }
    for (int i = 0; i < 2;i++){
        ListNode *tmp = (ListNode *)malloc(sizeof(ListNode));
        B->value = b[i];
        if(i!=1){
            B->next = tmp;
            B = tmp;
        }
        else if(i==0) headB = B;
        else B->next = NULL;
    }
    ListNode *res = addList(headA, headB);
    print(res);
    system("pause");
    return 0;
}

7.判断链表是否有环,求环的长度和入口点

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
} ListNode;
ListNode* enter(ListNode *head){
    ListNode *fast = head;
    ListNode *slow = head;
    if(head==NULL) return NULL;
    slow = slow->next;
    if(fast->next!=NULL) fast = fast->next->next;
    while(fast && fast!=slow){
        slow = slow->next;
        if(fast->next!=NULL) fast = fast->next->next;
    }
    if(fast==NULL) return NULL;
    slow = head;
    while(slow!=fast){
        slow=slow->next;
        fast = fast->next;
    }
    cout << fast->value << endl;
    return fast;
}
int dis(ListNode *head){
    ListNode *en = enter(head);
    ListNode *tmp = en->next;
    int res = 1;
    while(tmp!=en){
        tmp = tmp->next;
        res++;
    }
    return res;
}
void print(ListNode *head){
    int i = 0;
    while(head && i<10){
        i++;
        cout << head->value << " ";
        head = head->next;
    }
    return;
}
int main(){
    int n;
    cin >> n;
    ListNode *head = (ListNode *)malloc(sizeof(ListNode));
    ListNode *HEAD = (ListNode *)malloc(sizeof(ListNode));
    ListNode *en = (ListNode *)malloc(sizeof(ListNode));
    for (int i = 0; i < n;i++){
        int value;
        cin >> value;
        ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
        head->value = value;
        if(i==0){
            head->next = headd;
            HEAD = head;
            head = headd;
        }else if(i!=n-1 && i!=3){
            head->next = headd;
            head = headd;
        }else if(i==3){
            head->next = headd;
            en = head;
            head = headd;
        }else head->next = en;
    }
    print(HEAD);
    cout << dis(HEAD);
    system("pause");
    return 0;
}

8.判断两个不带环的链表是否相交,若相交,求交点。

lenA,lenB,长度差

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
} ListNode;
ListNode *getJoinP(ListNode *headA,ListNode *headB){
    int lenA = 0, lenB = 0;
    ListNode *HeadA = headA, *HeadB = headB;
    while(HeadA!=NULL){
        lenA++;
        HeadA = HeadA->next;
    }
    while(HeadB!=NULL){
        lenB++;
        HeadB = HeadB->next;
    }
    HeadA = headA;
    HeadB = headB;
    if(lenB>lenA){
        for (int i = 0; i < lenB - lenA;i++) HeadB = HeadB->next;
    }else if(lenB<lenA){
        for (int i = 0; i < lenA - lenB;i++) HeadA = HeadA->next;
    }
    while(HeadA!=HeadB){
        HeadA = HeadA->next;
        HeadB = HeadB->next;
    }
    return HeadA;
}
void print(ListNode *head){
    while(head){
        cout << head->value << " ";
        head = head->next;
    }
    return;
}
int main(){
    int a[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int b[10] = {10, 9, 8, 7, 6, 5, 6,7,8,9};
    ListNode *headA = (ListNode *)malloc(sizeof(ListNode));
    ListNode *headB = (ListNode *)malloc(sizeof(ListNode));
    ListNode *HEADA=(ListNode *)malloc(sizeof(ListNode));
    ListNode *HEADB=(ListNode *)malloc(sizeof(ListNode));
    for (int i = 0; i <3;i++){
        ListNode *headdA = (ListNode *)malloc(sizeof(ListNode));
        headA->value = a[i];
        if(i==0){
            HEADA = headA;
            headA->next = headdA;
            headA = headdA;
        }else if(i!=2){
            headA->next = headdA;
            headA = headdA;
        }
    }
    for (int i = 0; i < 10;i++){
        ListNode *headdB= (ListNode *)malloc(sizeof(ListNode));
        headB->value = b[i];
        if(i==0){
            HEADB = headB;
            headB->next = headdB;
            headB = headdB;
        }else if(i<3 || i>3 && i!=9){
            headB->next = headdB;
            headB = headdB;
        }else if(i==3){
            headA->next = headB;
            headB->next = headdB;
            headB = headdB;
        }else{
            headB->next = NULL;
        }
    }

    ListNode *tmpp = getJoinP(HEADA, HEADB);
    print(HEADA);cout << endl;
    print(HEADB);cout << endl;
    cout << tmpp->value;
    system("pause");
    return 0;
}

9.可能带环的两个链表的交点

1)两个都不带环,见8的解法

2)两个链表,一个带环,一个不带,这样一定不相交

3)两个都带环,有以下几种情况:

  • 当出现①情况时,两个链表不相交。
  • 当出现②情况时,两个链表的交点在环外,那么我们可以转化为不带环链表判断相交即可。
  • 当出现③情况时,两个链表的交点在环内,那么我们可以遍历其中一个链表的环,若在环内与另一个链表环的入口点相交,则两个链表相交,相遇点即为两个链表的交点。
  • 要判断为情况②还是情况③,只需判断两个链表环的入口点是否相同即可。

10.约瑟夫环

约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。通常解决这类问题时我们把编号从0~n-1,最后结果+1即为原问题的解。 求,最后一个出列的人的编号。

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
} ListNode;
ListNode *initList(int a[],ListNode *head,int n){
    ListNode *HEAD = head;
    for (int i = 0; i < n;i++){
        ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
        if(i!=n-1){
            head->value = a[i];
            head->next = headd;
            head = headd;
        }else{
            head->value = a[i];
            head->next = HEAD;
        }
    }
    return HEAD;
}
int main(){
    ListNode *head = (ListNode *)malloc(sizeof(ListNode));
    int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
    head = initList(a, head, 8);
    //第k个人开始从1报数,报到m则出列,下一个人从1继续报数,求最后一个出列的人。
    int k=2,m = 3;
    for (int i = 1; i < k-1;i++){
        head = head->next;
    }
    ListNode *pre = head;
    head = head->next;
    while (pre!=head){
        for (int i = 1; i < m;i++){
            head = head->next;
            pre = pre->next;
        }
        pre->next = head->next;
        free(head);
        head = pre->next;
    }
    cout << pre->value;
    system("pause");
    return 0;
}

11.冒泡排序用单链表实现

#include<iostream>
using namespace std;
typedef struct ListNode{
    int value;
    ListNode *next;
} ListNode;
void print(ListNode *head){
    while(head){
        cout << head->value << " ";
        head = head->next;
    }
    return;
}
ListNode *BubbleSort(ListNode *head,int n){
    ListNode *HEAD=head,*tmp=head->next,*pre=NULL;
    for (int i = 0; i < n;i++){
        tmp = HEAD->next;
        head = HEAD;
        pre = NULL;
        for (int j = i; j < n-1;j++){
            if(tmp->value<head->value){
                if(pre==NULL){
                    head->next = tmp->next;
                    tmp->next = head;
                    HEAD = tmp;
                }else{
                    pre->next = tmp;
                    head->next = tmp->next;
                    tmp->next = head;
                }
                pre = tmp;
                head = pre->next;
                tmp = head->next;
            }else{
                if(pre==NULL){
                    pre=head;
                    HEAD = head;
                }
                head = head->next;
                tmp = tmp->next;
            }
        }
    }
    return HEAD;
}
int main(){
    int a[] = {8, 6, 4, 3, 2, 67};
    ListNode *head = (ListNode *)malloc(sizeof(ListNode));
    ListNode *HEAD = (ListNode *)malloc(sizeof(ListNode));
    for (int i = 0; i < 6;i++){
        ListNode *headd = (ListNode *)malloc(sizeof(ListNode));
        if(i!=5){
            head->value = a[i];
            head->next = headd;
            if(i==0) HEAD=head;
            head = headd;
        } else{
            head->value = a[i];
            head->next = NULL;
        }   
    }
    head = BubbleSort(HEAD,6);
    system("pause");
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值