【链表】总结篇—链表的创建,插入和合并

本篇文章总结数据结构题目中出现有关于链表的知识点。

包括链表的声明(两种结构体的创建方法),链表的创建(头插法和尾插法),单/双链表的节点插入(已知前节点/后节点),有序链表的合并等。

1. 链表的声明

此处包含结构体的创建,声明为结构体变量和结构体指针变量的区别。以及两种定义指针变量,为变量申请空间的方法malloc/free和new/delete。

(1)结构体的创建:创建的时候可以根据typedef的类型,创建结构体指针结构体变量两种类型。

(2)结构体指针和结构体变量使用成员方式不同,分别为 . ->

(3)结构体指针需要申请空间(使用malloc和new),结构体变量不需要;

(4)定义时可定义指针,作为函数返回值,使用指针型返回值;

#include <iostream>
#include<malloc.h>
using namespace std;

typedef struct node{
    int val;
    node *next;
}Node,*Link;

typedef struct{
    string name;
    int age;
}student,*S;
int main()
{
    student s1;//定义结构体变量,使用.,且不需要申请空间
    s1.name="Tom";
    s1.age=13;

    Link n1,n2;//定义结构体指针,申请空间
    n1=new Node;
    n2=(Link)malloc(sizeof(Node));
    n1->val=1;
    n1->next=n2;
    n2->val=2;
    n2->next=NULL;
    delete []n1;
    free(n2);

    return 0;
}

2. 链表的创建

头插法和尾插法,三步和两步。

(1)头插法:两步,首先newNode->next=head->next,接着head->next=newNode

//使用头插法建立链表
void Creat_LinkList_HeadInsertion(ListNode *phead,int n){
    ListNode *p=phead;
    for(int i=0;i<n;i++)
    {
        ListNode *newNode=new ListNode;
        cin>>newNode->value;
        newNode->next=p->next;
        p->next=newNode;
    }
}

(2)尾插法:三步,首先newNode->next=NULL,其次p->next=newNode,最后p=p->next,p为移动的尾节点。

//使用尾插法建立链表
void Creat_LinkList(ListNode *phead,int n){
    ListNode *p=phead;
    for(int i=0;i<n;i++)
    {
        ListNode *newNode=new ListNode;
        cin>>newNode->value;
        newNode->next=NULL;
        p->next=newNode;
        p=newNode;
    }
}

3. 双向链表的创建

一般使用尾插法。所以依然是三步,不过加了对前指针pre的处理。首先对输入新节点初始化,即newNode->next=NULL,newNode->pre=NULL;其次插入进链表:newNode->next=p->next,p->next=newNode,加上一句newNode->pre=p;最后移动尾节点p=p->next。

同时,如果是双向循环链表还要将首尾相连,即最后p->next=head,head->pre=p。

//创建双向链表
void Create_double_LinkList(LinkNode *head,int m,char *a)
{
    LinkNode *p=head;
    for(int i=0;i<m;i++)
    {
        LinkNode *node=new LinkNode;
        node->value=a[i];
        node->freq=0;
 
        node->next=NULL;
        p->next=node;
        node->pre=p;
        p=p->next;
    }
    p->next=head;//如果是循环链表就要加这一句
    head->pre=p;
}

4. 链表的节点插入

包括已知前结点的插入和已知后节点的插入,以及双向链表中节点的插入。

(1)已知前节点:两步

//已知前节点:直接插入节点
newNode-next=p->next;
newNode->value=X;
p->next=newNode;

(2)已知后节点:将此节点值记录下来,新节点值赋给此节点,然后插入带有此节点的值的新节点到此节点后面,变成了已知前向节点的插入

//已知后节点:先保存值,再插入节点
newNode->value=p->value;
p->value=X;
newNode-next=p->next;
p->next=newNode;

(3)双向链表:四步,首先赋给本节点的后指向,其次改变后节点的前指向,接着改变本节点的前指向和前节点的后指向(这两个不分顺序)。

//将newNode插入p的后面
newNode->next=p->next;
p->next->pre=newNode;
p->next=newNode;
newNode->pre=p;

5. 链表中交换节点元素的次序

先取下本节点:一步将本节点的next赋给前节点的next即可。然后普通插入。

6. 有序链表的合并

类比于三元组存储矩阵,实现矩阵相加的的思想。

见例题:(62条消息) 【数据结构】NOJ004—单链表的归并_杨的博客-CSDN博客

(1)对于遍历两个有序链表,直接遍历一次即可;

(2)且不用申请新的节点空间,直接指向该节点,然后节点同时后移。类似于尾插法,p后移一位即可;

(3)掌握剩余链表的简洁插入法:pc->next=(pa==NULL?pb: pa)

void Merging_Linklist(LinkNode *headA,LinkNode *headB,LinkNode *headC)//归并链表
{
    LinkNode *pa=headA->next,*pb=headB->next,*pc=headC;
    while(pa!=NULL&&pb!=NULL)
    {
        if(pa->value<=pb->value)
        {
            pc->next=pb;
            pc=pc->next;
            pb=pb->next;
        }
        else
        {
            pc->next=pa;
            pc=pc->next;
            pa=pa->next;
        }
    }
    pc->next=(pa==NULL?pb:pa);//最后剩余的直接指向
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值