• 【23考研】408代码题参考模板——链表


    红色的为必须掌握
    有多个模板的只要掌握一种即可。

    单链表

    单链表结点结构体

    struct node{
    	int data;//数据
    	node *next;//指向下一个结点的指针 
    };
    
    • 1
    • 2
    • 3
    • 4

    其中数据域data的类型可以根据需要修改成其他的。

    单链表中间插入结点

    模板1

    以下两段代码本质是一样的,只不过一个在函数中new结点,一个结点在外面new好然后通过参数传进来

    void insert(node *p,int value){
    	//在p指向结点的后面插入一个值为value的结点
    	
    	//申请新节点的空间,上面是C写法,下面是C++写法 
    	//node *q=(node*)malloc(sizeof(node));
    	node *q=new node; 
    	
    	q->data=value; //先把数据放进去 
    	
    	//将q结点连进去 
    	q->next=p->next;
    	p->next=q;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    void insert(node *p,node *q){
    	//在p指向结点的后面插入一个结点q 
    	
    	q->next=p->next;
    	p->next=q;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    模板2

    以下两段代码本质是一样的,只不过一个在函数中new结点,一个结点在外面new好然后通过参数传进来

    void insert(node *p,int value){
    	//在p指向结点的后面插入一个值为value的结点
    	
    	//申请新节点的空间,上面是C写法,下面是C++写法 
    	//node *q=(node*)malloc(sizeof(node));
    	node *q=new node;
    	
    	q->data=value; //先把数据放进去 
    	
    	//将q结点连进去 
    	node *r=p->next; //r可能指向NULL,但不影响
    	p->next=q;
    	q->next=r;
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    void insert(node *p,int value){
    	//在p指向结点的后面插入一个结点q 
    	
    	node *r=p->next; //r可能指向NULL,但不影响
    	p->next=q;
    	q->next=r;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    单链表中删除结点

    以下两段代码本质是一样的,只不过一个是将删除的结点空间free掉,一个是返回(可能有其他用途,就是将这个结点从链表中摘下来)

    void del(node *p){
    	//删除p的后一个结点
    	//这里不考虑q为NULL的情况 
    	
    	node *q=p->next;//q为要删除的结点 
    	p->next=p->next->next; 
    	
    	//释放结点空间,上面是C写法,下面是C++写法 
    	//free(q); 
    	delete q;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    node* del(node *p){
    	//删除p的后一个结点,并将该结点返回 
    	//这里不考虑q为NULL的情况 
    	
    	node *q=p->next;//q为要删除的结点 
    	p->next=p->next->next; 
    	
    	return q; //将从链表中删除的结点返回 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    遍历链表(以求链表长度和查找元素为例)

    模板1

    int length(node *head){
    	//返回单链表的长度
    	
    	int cnt=0; //计数器,初始为0 
    	
    	//遍历单链表中的所有结点 
    	for(node *p=head->next;p!=NULL;p=p->next){
    		cnt++; //计数器+1 
    	} 
    	
    	return cnt;  
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    node* find(node *head,int value){
    	//查找单链表中是否有元素value
    	//有则返回该结点,无则返回NULL
    	
    	for(node *p=head->next;p!=NULL;p=p->next){
    		if(p->data == value){
    			//找到了,返回该结点 
    			return p;
    		}
    	} 
    	
    	return NULL;//没找到,返回NULL 
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    模板2

    int length(node *head){
    	//返回单链表的长度
    	
    	int cnt=0; //计数器,初始为0 
    	
    	//遍历单链表中的所有结点 
    	node *p=head->next; //p指向链表中第一个元素所在的结点 
    	while(p!=NULL){
    		cnt++; //计数器+1 
    		p=p->next;//p指向下一个结点 
    	} 
    	
    	return cnt;  
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    node* find(node *head,int value){
    	//查找单链表中是否有元素value
    	//有则返回该结点,无则返回NULL
    	
    	node *p=head->next;//p指向链表中第一个元素所在的结点
    	while(p!=NULL){
    		if(p->data == value){
    			//找到了,返回该结点 
    			return p;
    		}
    		p=p->next;//p指向下一个结点
    	} 
    	
    	return NULL;//没找到,返回NULL 
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    头插法建立单链表

    这里用到了前面在链表中插入结点的insert()函数,在考试时需要将insert()函数写上

    node* head_insert(int A[],int n){
    	//将数组A中的元素以头插法的形式插入链表中
    	//返回链表的头结点
    	
    	node *head=new node;//头结点 
    	head->next=NULL; //一开始链表中没有元素 
    	
    	for(int i=0;i<n;i++){
    		//由于是头插法,所以在头结点后面插入一个结点
    		insert(head,A[i]); 
    	}
    	 
    	return head; //返回链表的头结点 
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    尾插法建立单链表

    这里用到了前面在链表中插入结点的insert()函数,在考试时需要将insert()函数写上

    node* tail_insert(int A[],int n){
    	//将数组A中的元素以尾插法的形式插入链表中
    	//返回链表的头结点
    	
    	node *head=new node;//头结点 
    	head->next=NULL; //一开始链表中没有元素 
    	node *tail=head; //尾指针 
    	
    	for(int i=0;i<n;i++){
    		insert(tail,A[i]);//由于是尾插法,所以在尾结点后面插入一个结点  
    		tail=tail->next;//更新尾指针的值 
    	}
    	
    	return head; //返回头结点 
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    链表元素逆置

    采用头插法的方法,将链表中原来的结点一个个摘下来放入新的链表中

    模板1

    void reverse(node *head){
    	//将链表中的元素逆置 
    	
    	node *head2=(node*)malloc(sizeof(node));//新链表的头结点
    	//node *head2=new node;
    	head2->next=NULL;
    	
    	//每次摘下原链表的第一个结点 
    	while(head->next!=NULL){ //原链表中还有结点 
    		 
    		 node *p=head->next;//将第一个结点摘下
    		 head->next=head->next->next;//原链表接上后面的结点 
    		 
    		 //以头插法将p结点插入新链表中
    		 p->next=head2->next;
    		 head2->next=p;
    		 
    	} 
    	
    	head->next=head2->next; //将原先的头结点指向新的链表 
    	free(head2);//因为已经将原先的头结点指向新的链表,所以head2就没用了 
    	//delete head2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    模板2

    用到前面的insert()和del()函数,考试时需要写上

    void insert(node *p,node *q){
    	//在p指向结点的后面插入一个结点q 
    	
    	q->next=p->next;
    	p->next=q;
    }
    
    node* del(node *p){
    	//删除p的后一个结点,并将该结点返回 
    	//这里不考虑q为NULL的情况 
    	
    	node *q=p->next;//q为要删除的结点 
    	p->next=p->next->next; 
    	
    	return q; //将从链表中删除的结点返回 
    }
    
    void reverse(node *head){
    	//将链表中的元素逆置 
    	
    	node *head2=(node*)malloc(sizeof(node));//新链表的头结点
    	//node *head2=new node;
    	head2->next=NULL;
    	
    	//每次摘下原链表的第一个结点 
    	while(head->next!=NULL){ //原链表中还有结点 
    		 node *p=del(head);//将第一个结点摘下
    		 insert(head2,p);//以头插法将p结点插入新链表中
    	} 
    	
    	head->next=head2->next; //将原先的头结点指向新的链表 
    	free(head2);//因为已经将原先的头结点指向新的链表,所以head2就没用了 
    	//delete head2;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    获取链表中间结点(双指针法,快慢指针)

    node* get_mid(node *head){
    	//获取链表的中间结点,双指针法
    	node *p=head;//快指针
    	node *q=head;//慢指针
    	
    	while(p!=NULL && p->next!=NULL){
    		//p不为空结点且p不是最后一个结点
    		
    		//快指针p走两步
    		p=p->next;
    		p=p->next;
    		
    		//慢指针走一步
    		q=q->next; 
    	} 
    	
    	//p走到末尾时,q刚好在中间位置 
    	return q;
    } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    双链表

    双链表结点结构体

    struct node{
    	int data; //数据域 
    	node *pre; //指向前一个结点的指针 
    	node *next; //指向后一个结点的指针 
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    双链表中插入结点

    模板1

    void insert(node *p,node *q){
    	//在p结点后插入结点q 
    	//以下顺序不唯一,只要不断链就行 
    	q->next=p->next;
    	q->pre=p;
    	if(q->next!=NULL){
    		q->next->pre=q;
    	} 
    	p->next=q;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    模板2

    void insert(node *p,node *q){
    	node *r=p->next;//r可能指向NULL 
    	//以下顺序任意 
    	p->next=q;
    	q->pre=p;
    	q->next=r;
    	if(r!=NULL){
    		r->pre=q;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    双链表中删除结点

    模板1

    node* del(node *p){
    	//将p结点后面的结点从链表中删除,并将删除的结点返回
    	//这里不考虑p后面结点为NULL的情况 
    	
    	node *q=p->next; //q为要删除的结点 
    	p->next=p->next->next;
    	if(p->next!=NULL){
    		p->next->pre=p;
    	}
    	return q;//将链表中删除的结点返回 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    模板2

    node* del(node *p){
    	//将p结点后面的结点从链表中删除,并将删除的结点返回
    	//这里不考虑p后面结点为NULL的情况 
    	node *q=p->next;
    	node *r=q->next;//r可能指向NULL
    	p->next=r;
    	if(r!=NULL){
    		r->pre=p;
    	}
    	return q; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    双链表的遍历

    参考单链表的遍历

  • 相关阅读:
    CdSe/ZnTe Ⅱ型核壳量子点/核壳型功能/SiC碳化硅量子点的合成
    Autofac 注入仓储模式
    Vue3 分页
    观察神秘的RQ
    python项目之酒店客房入侵检测系统的设计与实现
    vue-router安装报错、版本冲突
    洛谷 P3390 【模板】矩阵快速幂
    是否在CLI模式下
    蓝桥杯 题库 简单 每日十题 day13
    Java基础之浅聊 CompletableFuture类
  • 原文地址:https://blog.csdn.net/qq_50710984/article/details/126064614