03链表[数据结构学习笔记](注释比代码多)

#学习笔记,望路过的大佬帮忙指出错误,感激万分

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define ERROR 1
#define FALSE 0
#define OK 1
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status; 

// 声明一个结构体表示结点 
typedef struct Lnode{
    
    
	int data;	//定义结点的数据域 
	struct Lnode *next;		//定义结点的指针域 
}Lnode,*LinkList;	//LinkList为指向Lnode的指针类型 

//	头插法创建链表 
LinkList CreateList_H(LinkList &L, int n){
    
    	//Create创建 ,_H头插法 ,参数LinkList &L为头指针,参数n为链表的结点个数 
	L=(LinkList)malloc(sizeof(Lnode));	//让指针L指向一个空结点 
	L->next=NULL;	//先建立一个带头结点的单链表
	printf("请输入%d个数,以空格隔开:\n",n);
	for(int i=1;i<=n;i++){
    
    
		Lnode *p;	//定义一个结点指针p 
		p=(LinkList)malloc(sizeof(Lnode));	//为结点指针开辟一个结点;
		scanf("%d",&p->data); 	//为结点p的数据域赋值 
		p->next=L->next;		//让该结点的指针域指向头结点 
		L->next=p;		//让头指针指向该结点 
	} 
	return L; 
} 

// 尾插法创建链表
LinkList CreateList_R(LinkList &L, int n){
    
    	//Create创建 ,_R尾插法 ,参数LinkList &L为头指针,参数n为链表的结点个数 
	L=(LinkList)malloc(sizeof(Lnode));	//让指针L指向一个空结点 
	L->next=NULL;	//先建立一个带头结点的单链表
	Lnode *r=L;		//定义一个结点指针r作为尾指针 ,初始化指向头结点(只有一个结点是头结点则为尾结点) 
	printf("请输入%d个数,以空格隔开:\n",n);
	for(int i=1;i<=n;i++){
    
    
		Lnode *p;	//定义一个结点指针p 
		p=(LinkList)malloc(sizeof(Lnode));	//为结点指针开辟一个结点;
		scanf("%d",&p->data); 	//为结点p的数据域赋值
		p->next=NULL;	  //因为是尾插法,所以新创建的结点必须为尾结点则指针域为空
		r->next=p;		 //r原来指的尾结点成为倒数第二个结点,所以该结点的指针域指向尾结点p 
		r=p; 		    //由因为p为尾结点,则将p赋值给r,则r为尾结点,即r成为新的尾指针指向尾结点。 
		
	} 
	
	return L; 
}  

//	输出链表
void PrintList_L(LinkList &L){
    
    
	Lnode *p;
	int count=1;
	p=L->next;
	while(p){
    
    
		printf("%d ",p->data);
		p=p->next;
		count++;	
	}
	printf("\n链表的结点数为%d(包含头结点)",count);
	printf("\n----------------------------\n");
} 

//获取单链表第i个元素的内容,通过(引用)变量e返回该值
Status GetElem_L(LinkList L,int i,int &e){
    
    
	Lnode *p;
	int count=1;	//计算器为了找打第i个元素 
	p=L->next;	//让指针p指向首元结点
	while(p&&count<i){
    
    
		p=p->next;	//让指针指向下一个结点 
		count++; 
	}
	if(!p||count>i)return ERROR;
	e=p->data;
	return ERROR; 
	return OK;
	
} 

//插入
Status ListInsert_L(LinkList &L,int i,int e){
    
    
	Lnode *p;
	int count=1;//计算器为了找打第i个元素 
	p=L->next;	//让指针p指向首元结点
	while(p&&count<i-1){
    
    	//寻找第i-1个结点 
		p=p->next;	//让指针指向下一个结点
		count++;
	} 
	if(count>i-1||!p)return ERROR;
	Lnode *s; 
	s=(LinkList)malloc(sizeof(Lnode));	//为结点指针开辟一个结点; 
	s->data=e;
	s->next=p->next;
	p->next=s;
	return OK;
} 

//删除 第i个元素,并由e返回其指 
Status ListDelete_L(LinkList &L,int i,int &e){
    
    
	Lnode *p;
	int count=1;//计算器为了找打第i个元素 
	p=L->next;	//让指针p指向首元结点
	while(p->next&&count<i-1){
    
    	//寻找第i-1个结点 
		p=p->next;	//让指针指向下一个结点
		count++;
	} 
	if(count>i-1||!(p->next))return ERROR;
	Lnode *q; 	
	q=p->next;	//让q指向下一个结点即2号结点,我们要删的结点  	
 	p->next=q->next;	//将为2号结点的指针域赋值给1号结点
 	e=q->data;	//由e返回其指 
	delete q; 	//删除2号结点
	return OK; 
} 

// 合并两个非递减的链表
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){
    
    
	Lnode *pa,*pb,*pc;
	pa=La->next;	//pa指向La的首元结点 
	pb=Lb->next;	//pb指向Lb的首元结点
	pc=La;			//pc指向La的头结点
	Lc=La;			//令Lc为Lc的头结点 
	while(pa&&pb){
    
    	//La和Lc一旦有一个排完则跳出循环 
		if(pa->data<=pb->data){
    
    
		pc->next=pa;		//将pa赋值给Lc的首元结点 
		pa=pa->next; 	  //pa指向下一个结点
		}
		else {
    
    	
		pc->next=pb;	//将pb赋值给Lc的首元结点 	
		pb=pb->next; 	//pb指向下一个结点 
		}
		pc=pc->next;	//pc指向下一个结点
	}
	pc->next=pa?pa:pb; //将未排的加到后面
	free(Lb);
}

 
int main(){
    
     
	//声明两个链表的变量 
	LinkList L_H,L_R;
	//头插法建立链表 
	CreateList_H(L_H,5);
	//尾插法建立链表 
	CreateList_R(L_R,5);
	//输出头插法建立的链表 
	PrintList_L(L_H);
	//输出尾插法建立的链表 
	PrintList_L(L_R);
	
	int e;
	int i=4;
	//获取第i个位置的数据域,e返回该值 
	GetElem_L(L_R,i,e);
	printf("第%d个数为%d\n",i,e);
	//在第i个位置插入新结点 
	ListInsert_L(L_R,i,e);
	printf("在第%d个位置,插入%d后,链表为:\n",i,e);
	PrintList_L(L_R);
	//删除第i个位置的结点 
	ListDelete_L(L_R,i,e); 
	printf("删除第%d个位置后,链表为:\n",i);
	PrintList_L(L_R);
	// 合并两个非递减的链表
	LinkList L;
	MergeList_L(L_R,L_H,L);
	PrintList_L(L);
}


猜你喜欢

转载自blog.csdn.net/Ustinianljm/article/details/121876677