数据结构——基于C语言的单链表应用

【数据结构】:
typedef int ElemType;
typedef struct Node{
	ElemType data;
	struct Node *next;}Node,*LinkList;  //初始化单链表

【算法思想】
(1)初始化:我们先初始化建立一张空的单链表。
(2)添加结点:本次实验我使用了尾插法,该方法是将新结点插到当前单链表的表尾上。为此需增加一个尾指针r,使之指向当前单链表的表尾。
(3)按序号查找:在单链表中,由于每个结点的存储位置都放在其前一结点的next域中,所以即使知道被访问结点的序号i,也不能像顺序表那样直接按序号i访问一维数组中的相应元素,只能从链表的头指针出发,顺链域next逐个结点往下搜索,直至搜索到第i个结点为止。
(4)查找单链表中的数据:采用指针P依次指向各个结点,并附设计数器j计数,判断输出链表数据。
(5)插入操作:找到单链表中第i-1个结点并由指针pre指示,再申请一个新结点,将其数据域的值置为e。
(6)通过修改指针域将新结点s挂入单链表L。
(7)删除操作:通过计数方式找到第i-1个结点并由指针pre指示,删除第i个结点并释放结点空间。
(8)合并有序表:首先我们要输入两张表,要求利用现有的表LA和LB中结点空间来建立新表LC,可通过更改结点的next域来重建新的元素之间的线性关系。为保证新表仍然递增有序,可以利用尾插入法建立单链表。

【算法描述】:

(1)初始化表


LinkList InitList(LinkList L){  
L=(LinkList)malloc(sizeof(Node));//这是动态分配,分配的空间大小,建立头结点。 
//	if(!L->next)    //把指针看成整型,指针为NULL相当于指针等于零。所以L.elem==NULL则!L.elem为真。  判断空间分配是否成功
//	return ERROR;  //创建失败则返回0; 
	  (L)->next=NULL;  //建立空的单链表L 
	return L;
} 	

(2) 尾插法添加结点

int CreateFromTail(LinkList L){
 	char c;
 	Node *r,*s;
 	int flag = 1;
 	r=L;	
 	while(flag){
 	  	scanf("%d",&c);
 	  	if(c!=-100){
 	  		s=(Node*)malloc(sizeof(Node));
 	  		s->data=c;
 	  		r->next=s;
 	  		r=s;
		   }else{	   	
		   	flag=0;
		   	r->next=NULL;
		   }
	 }
	 return OK;
 } 

(3)查找的函数(按序号查找)

int Get(LinkList L,int i){
int j;
Node *p;
	if(i<=0)return ERROR;
	p=L;j=0;      //从头开始扫描
	while((p->next!=NULL)&&(j<i)) 
	{
		p=p->next;
		j++;
	}
	if(i==j) {
		printf("你查找的第%d位的结点,数值是%d\t",i,p->data);
		return OK;
	}
	else return ERROR;
} 

(4)据长度输出单链表的数据

int Cha(LinkList L){
 	 Node * p;
 	 p=L->next;
 	 int j=0;
 	 while(p!=NULL){
 	 	printf("%d\t",p->data);
 	 	p=p->next;
 	 	j++;
	  }	 
 	return OK;
 } 

(5)插入操作

int InsList(LinkList L,int i,ElemType e){
 	//在带头结点的单链表L中第i个位置插入值为e的新结点。 
 	Node *pre,*s;
 	int k;
 	if(i<=0) return ERROR;
 	pre=L;k=0;   //从头开始查找第i-1个结点。 
	while(pre!=NULL&&k<i-1){   //一直循环,直到找到pre指向第i-1个
		pre=pre->next;
		k=k+1;	
	} 
	if(pre==NULL){
		printf("插入位置不合理。");
		return ERROR;
	}
	s=(Node*)malloc(sizeof(Node));
	s->data=e;
	s->next=pre->next;
	pre->next=s;
	return OK; 
 } 

(6) /单链表的删除操作

int DelList(LinkList L,int i,ElemType e){
	Node *pre,*r;
	int k;
	pre=L;k=0;
	while(pre->next!=NULL&&k<i-1){   //  2
		pre=pre->next;
		k=k+1;
	}
	if(pre->next==NULL){
		printf("删除结点的位置不合法!");
		return ERROR;
	}
	r=pre->next;
	pre->next=r->next;   //修改指针,删除结点。 
	e=r->data;    
	free(r);    //释放结点 
	return OK;
}

(7)合并两个有序表

LinkList MergeLinkList(LinkList LA,LinkList LB){
	Node *pa,*pb,*r;
	LinkList LC;
	pa=LA->next;
	pb=LB->next;
	LC=LA;
	LC->next=NULL;
	r=LC;
	while(pa!=NULL&&pb!=NULL){
		if(pa->data<=pb->data){
			r->next=pa;r=pa;pa=pa->next;
		}else{		
			r->next=pb;r=pb;pb=pb->next; 
		}
	}
	if(pa)
	r->next=pa;
	else
	r->next=pb;
	free(LB);
	return(LC);
} 

(8)最后就是在main函数中调用了。

int main(){
	int i,x,y;
	LinkList LA,LB,LC;
	Node *L;
	ElemType e;
	LA=InitList(LA);
//	if(i==1)printf("成功!");
	printf("输入你要添加的结点,以-100结束:\n");
	i=CreateFromTail(LA);
	if(i==1)Cha(LA);
	printf("\n你输入你要查找的序号:\n");
	scanf("%d",&i);
    i=Get(LA,i);
	if(i==1)printf("查找成功!\n");
	else printf("结点序号不正确\n");
	printf("请输入要插入的结点位置:\n");
	scanf("%d",&x);
	printf("\n请输入要插入的结点数据:\n");
	scanf("%d",&y);
    i=InsList(LA,x,y);
    if(i==1)Cha(LA);
    printf("\n请输入要删除的结点位置:\n");
    scanf("%d",&x);
    i =DelList(LA,x,e);
    if(i==1)Cha(LA); 
    printf("\n请输入第二张单链表结点,以-100结束:\n");
    LB=InitList(LB);  //初始化 
    i=CreateFromTail(LB);
	if(i==1)Cha(LB);
    printf("\n接下来就是合并了:\n");
    LC=MergeLinkList(LA,LB);
    if(LC!=NULL)Cha(LC);  
} 

(9)最后运行的示意图:
在这里插入图片描述
源码下载:
https://download.csdn.net/download/weixin_42868605/21006682

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

掉色的熊猫

大爷,赏点吧。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值