数据结构—单链表(C/C++版)

本文为CSDN博主coder_gxd原创

转载请注明:https://blog.csdn.net/coder_gxd/article/details/79827262


本文介绍数据结构中单链表的常用算法(C/C++版),欢迎各位同学讨论指正。

#include <stdlib.h>//函数malloc(),free()所在头文件
//本文单链表为含有头结点的单链表

//单链表结点的定义 
typedef struct LNode{
	int data;//数据域 data ,以 int类型 为例 ; 
	struct LNode *next;//后继结点指针域; 
}LNode; 

//尾插法建立单链表,算法复杂度O(n); 
//将数组a[]中的数据依次插入到单链表尾部,数组a[]中共 n 个元素;
void creatlistR(LNode *&C,int a[],int n){
	LNode *s;//s用来指向新申请的结点
	LNode *r;//r用来指向链表C的终端结点
	C=(LNode *)malloc(sizeof(LNode)); 
	C->next=NULL;//这两句建立链表C的头结点
	r=C;//r指向C,此时头结点就是终端节点
	for(int i=0;i<n;i++){
		s=(LNode *)malloc(sizeof(LNode));//s用于指向新申请的结点
		s->data=a[i];//新申请的节点接收a[]中元素
		r->next=s;//将新结点链在终端结点后
		r=r->next;//终端结点后移一个 
	} 
	r->next=NULL;//a[]中元素导入完毕,C的终端结点指向NULL; 
}

//头插法建立单链表,算法复杂度O(n); 
//将数组a[]中的数据依次插入到单链表头部,数组a[]中共 n 个元素;
void creatlistF(LNode *&C,int a[],int n){
	LNode *s;//s用来指向新申请的结点
	C=(LNode *)malloc(sizeof(LNode)); 
	C->next=NULL;//这两句建立链表C的头结点
	for(int i=0;i<n;i++){
		s=(LNode *)malloc(sizeof(LNode));//s用于指向新申请的结点
		s->data=a[i];//新申请的节点接收a[]中元素
		s->next=C->next;//将新结点链在头结点后
		C->next=s;//终端结点后移一个 
	} 
}

//尾插法建立单链表,单链表的归并操作 ,算法复杂度O(max(p.length,q.length))
//A,B是两个单链表,带头结点,其中,元素递增有序。将A,B归并成一个按元素值“非递减”有序的链表C,C中结点由A和B组成
void mergeR(LNode *A,LNode *B,LNode *&C){
	LNode *p=A->next;//p用来跟踪A中最小的结点;
	LNode *q=B->next;//q用来跟踪B中最小的结点;
	LNode *r;//r用来指向C的终点结点
	C=A;C->next=NULL;//用A的头结点来做C的头结点;
	free(B);// B的头结点已无用,释放掉;
	r=C;//r指向C结点,此时头结点也是重点节点;
	while(p!=NULL&&q!=NULL){
		if(p->data<=q->data){//p结点的数据小于q结点的数据,p结点尾插入C的尾端; 
			r->next=p;
			p=p->next;
			r=r->next;
		} 
		else{//q结点的数据小于p结点的数据,q结点尾插入C的尾端; 
			r->next=q;
			q=q->next;
			r=r->next;
		} 
	}
	r->next=NULL;//可以省略,因为下面两个if语句必然执行一个
	if(p!=NULL)	r->next=p; 
	if(q!=NULL)	r->next=q;//这两句将剩余的结点链在C的尾部 
}
 
//头插法建立单链表,单链表的归并操作 ,算法复杂度O(p.length+q.length)
//A,B是两个单链表,带头结点,其中,元素递增有序。将A,B归并成一个按元素值“非递增”有序的链表C,C中结点由A和B组成
void mergeL(LNode *A,LNode *B,LNode *&C){
	LNode *p=A->next;//p用来跟踪A中最小的结点;
	LNode *q=B->next;//q用来跟踪B中最小的结点;
	LNode *s;//s用来指向被操作结点(p或者q),方便操作,相当于中间变量; 
	C=A;C->next=NULL;//用A的头结点来做C的头结点;
	free(B);// B的头结点已无用,释放掉;
	while(p!=NULL&&q!=NULL){
		if(p->data<=q->data){//p结点的数据小于q结点的数据,p结点尾插入C的开始结点处; 
			s=p;p=p->next;
			s->next=C->next;
			C->next=s; 
		} 
		else{//q结点的数据小于p结点的数据,q结点尾插入C的开始结点处;
			s=q;q=q->next;
			s->next=C->next;
			C->next=s;
		} 
	}
	while(p!=NULL){//将A中剩余的结点逐个键连在C的开始结点处; 
		s=p;p=p->next;
		s->next=C->next;
		C->next=s; 
	}
	while(p!=NULL){//将B中剩余的结点逐个键连在C的开始结点处; 
		s=q;q=q->next;
		s->next=C->next;
		C->next=s;
	}
}

//查找链表中元素并删除; 
//查找链表C(带头结点)中值为x的一个结点,若存在,删除并返回1,否则返回0; 
int findAndDlete(LNode *&C,int x){
	LNode *p;//q结点用来查找目标结点的前一个结点 
	LNode *q;//q结点用来要被删除的结点 
	p=C;//p结点从C头结点开始遍历
	while(p->next!=NULL){//查找目标结点 
		if(p->next->data==x){
			break;
		} 
		p=p->next;
	} 
	if(p->next==NULL)	return 0;//查询失败,返回 0;
	else{//查询成功,删除结点 
		q=p->next;//目标结点赋给 q ; 
		p->next=q->next;
		free(q);
		return 1;
	} 
} 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值