【国庆出大力】c/c++实现单链表的创建、插入、删除、逆置、归并

因为本人要准备考研了,关于前端的东西占比会变少,不过还是和计算机相关的内容,大家多了解一点也无妨。最近在复习901数据结构与算法设计,当然也是各大公司笔试题的一部分。主要代码都是c/c++,因为四年没写了,突然上手写的很渣==如果有需要改进的地方请留言,我看到会及时的修改。
有图片上传不成功点击github原文

《【国庆出大力】c/c++实现单链表的创建、插入、删除、逆置、归并》 demo

创建链表

头插入

[图片上传失败…(image-85d3-1538919156505)]

#include<iostream>
#include "stdio.h"
#include "stdlib.h"
using namespace std;

struct LNode{
    int data; // 数据域 
    LNode *next; // 指向自身的指针域 
};
typedef LNode *LinkList; 

LinkList createLinkList Head(){
LinkList L;
LinkList p;
int x;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
cin>> x;
while(x!=0) {
    p=(LinkList)malloc(sizeof(LNode));
    p->data=x;
    p->next=L->next;
    L->next=p;
    cin>>x;
};
return L;
}

int main(){
createLinkListHead();
}

查找

按序号查

LinkList findNodeByOrder(LinkList L,int target){
    LinkList p=L;
    int i=0;
    while(i<target&&p->next!=NULL){
        p=p->next;
        i++;
    }
    if(i==target){
        return p;
    }
    return NULL;
}

按数据查

int findNodeByValue(LinkList L,int target){
    LinkList p=L;
    while(p->data!=target&&p->next!=NULL){
        p=p->next;
    }
    
    return p->data;
}

插入

指定在某个序号前插入某个值

LinkList insertBefore(LinkList L,int s,int target){ // target为指定插入位置的数据域为s的节点 
    LinkList p=L;
    LinkList newNode=(LinkList)malloc(sizeof(LNode));
    newNode->data=s;
    int i=0; 
    if(target<1){
        printf("参数target错误"); 
        exit(1);
    }
    while(i<target-1){
        i++;
        p=p->next;
    }
        // 现在的p是目标节点的前驱 
        newNode->next=p->next;
        p->next=newNode;
    return L;
}

删除

删除单链表第i个节点

LinkList deleteByOrder(LinkList L,int i){
    // 仍然是找前驱 
    LinkList p=L;
    LinkList q;
    int j=0;
    while(j<i-1){
        p=p->next; 
        j++;
    }
    if(p==NULL||j>i-1){
        printf("参数i错误");
        exit(1);
    } 
    q=p->next; // 目标节点
    p->next=q->next;
    free(q);
    return L;
}

双向链表

创建双向链表

struct DuLNode{
    int data;
    DuLNode *next;
    DuLNode *prior;
}; 
typedef DuLNode *DuLinkList;

DuLinkList createDoubleLinkList(){
    DuLinkList head,L;
    DuLinkList p;
    int x;
    L=(DuLinkList)malloc(sizeof(DuLNode));
    head=L;
    cin>>x;
    while(x!=0){
        p=(DuLinkList)malloc(sizeof(DuLNode));
        p->data=x;
        p->next=NULL;
        p->prior=L;
        L->next=p;
        L=p; 
        cin>>x;
    }
    return head;
}

双向链表插入节点

在双向链表第i个节点前插入数据域为x的节点。还是先连后断,因为是双向链表有前驱指针不用找第i+1个元素了。先把新节点s的前驱后继连上,然后断开目标节点p的前驱节点的后继指针,将他连到s上,然后再操作目标节点p的前驱指向新节点!!

DuLinkList DuLinkInsert(DuLinkList L,int i,int x){
    DuLinkList head,s,p;
    int n=0;
    p=L;
    head=L;
    s=(DuLinkList)malloc(sizeof(DuLNode));
    s->data=x; 
    while(n<i){
        p=p->next;
        n++;
    }
    if(i==n){
        s->next=p;
        s->prior=p->prior;
        p->prior->next=s;
        p->prior=s;
        return head;
    }else{
        cout<<"参数i错误"<<endl;
        exit(1);
    }
}

双链表删除节点

还是删除i位置的节点p,p的前驱节点的后继与p的后继相同,p的后继节点的前驱与p的前驱指针相连,释放p。

DuLinkList DuLinkDelete(DuLinkList L,int i){
    DuLinkList head,p;
    int n=0;
    p=L;
    head=L;
    while(n<i){
        p=p->next;
        n++;
    }
    if(i==n){
        p->prior->next=p->next;
        p->next->prior=p->prior;
        free(p);
        return head;
    }else{
        cout<<"参数i错误"<<endl;
        exit(1);
    }
}

扩展

合并两个链表

Node* mergelistByOrder(Node *l1,Node *l2){
    Node *head,*L;
    L=new Node;
    L->next=NULL;
    L->data=0;
    head=L;
    while(l1&&l2){
        if(l1->data<l2->data){
            L->next=l1;
            l1=l1->next;
        }else{
            L->next=l2;
            l2=l2->next;    
        }
        L=L->next;
    }
    if(l1){
        L->next=l1;
    }
    if(l2){
        L->next=l2;
    }

    return head->next;
}

链表原地逆置

原地逆置需要两个指针p,q,和一个临时指针t。q是p的后继,然后将q->next指向p。最终循环完要先断开头节点与这个链表之间的后继关系,将头节点的后继指向p。具体见这个图示->链表原地反转

Node* reverse(Node* L){
    Node *p,*q,*t,*head;
    head=L;
    p=head->next;
    q=head->next->next;
    while(q!=NULL){
    t = q->next;  
    q->next = p;  
    p = q;  
    q = t;
    }
    head->next->next=NULL;
    head->next=p;
    return head;
}

两个升序链表,降序合并

  1. 第一个方法是将上面两个方法结合起来,先按顺序合并,然后逆置。
  2. 第二个方法是通过头插法,选择最小的先插入。
Node* mergelistByDescOrder(Node *l1,Node *l2){
    Node *L,*head,*t,*q;
    L=new Node();
    head=L;
    while(l1&&l2){
        if(l1->data<l2->data){
            t=l1;
            l1=l1->next;
        }else {
            t=l2;
            l2=l2->next;
        }
        t->next=L->next;
        L->next=t;
        //L=t;
        t=NULL; 
    }
    // 如果l1和l2循环之后还有剩余的节点,按顺序依次添加到头节点之后
    if(l1){
        t=l1;
    }
    if(l2){
        t=l2;
    }
    while(t){
        q=t;
        t=t->next;
        q->next=L->next;
        L->next=q;
    }
    return head->next;
} 

最后请大家关注我的订阅号获得更加及时的推送~

《【国庆出大力】c/c++实现单链表的创建、插入、删除、逆置、归并》 那屋水泡

    原文作者:5ed1bc7b3716
    原文地址: https://www.jianshu.com/p/a374f87833f8
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞