单链表

单链表的结点存储结构定义如下:

typedef struct Node

{

Datatype data;

struct Node *next;

}LNode,*LinkList;

LNode是结点类型,LinkList指向Lnode类型结点的指针类型,即LinkList等同于LNode*

要完成申请一块LNode类型的存储单元的操作,则需执行如下语句:

p=(LinkList)malloc(sizeof(LNode));

单链表的基本运算实现:

1建立单链表

(1)在链表的头部插入结点建立单链表

#define flag -1

void Create_LinkList1(ListList L)
{
	LNode *s;
	Datatype x;
	scanf("%d",&x);
	while(x!=flag){
		s=(LinkList)malloc(sizeof(LNode));
		s->data=x;
		s->next=L->next;
		L->next=s;
		scanf("%d",&x);
	}
 } 

如果调用函数是main函数,主函数对建立单链表的调用如下:

void main()

{

LinkList L;

L=(LinkList)malloc(sizeof(LNode));

L->next=NULL;

Create_LinkList1(L);

}

(2)在链表的尾部插入节点建立单链表

尾部插入元素读取数据元素的顺序为顺序

 void Create_LinkList2(LinkList L)
 {
 	LNode *r,*s;//s为指向当前插入元素的指针,r为尾指针 
 	DataType x;
 	scanf("%d",&x);
	 r=L;
	 while(x!=flag)
	 {
	 	s=(LinkList)malloc(sizeof(LNode));
	 	s->data=x;
	 	s->next=r->next;
	 	r=s;
	 	scanf("%d",&x);
	  } 
	  r->next=NULL;
 }

2查找运算

(1)按序号查找

给定序号i查找出单链表第i个元素的结点指针

思路:从链表的第一个元素开始,判断当前结点是否是第i个结点,若是返回该结点的指针,否则下一个,直到链表结束为止。没有第i个节点返回空指针。

LNode  *Get_LinkList(LinkList L,int i)
 {
 	LNode *p;
 	int j;//j是计数器,用来判断当前结点是否是第i结点 
 	p=L;
 	j=0;
	 while(p!=NULL&&j<i)
	 {
	 	p=p->next;//判断当前结点p不是第i个且p非空,则p移向下一个 
	 	j++;
	  } 
	return  p;  
 }

(2)按值查找

思路:从链表的第一个元素开始,判断当前结点值是否等于x,若是则返回该结点指针,否则继续后一个,直至链表结束。

 LNode *Location_LinkList(LinkList  L,Datatype  x)
 {
 	LNode *p;
 	p=L->next;
 	while(p!=NULL&&p->data!=x)
 	{
 		p=p->next;
	 }
	 return p;
  } 

3插入算法

(1)插入结点

设p指向单链表中某元素a的结点,s指向待插入的值为x的新节点,将s插入到p结点的后面,插入语句如下:

s->next=p->next;

p->next=s;

(2)单链表的插入运算

将一个值为x的节点插入到单链表的第i个位置,这就要求查找到第i-1个结点指针p,若p存在,在p后面执行插入新节点操作,否则结束

  void Insert_LinkList(LinkList L,int i,Datatype x)
  //在单链表L中第i个位置插入x结点 
  {
  	LNode *p,*s;
	  p=Get_LinkList(L,i-1);//寻找到第i-1个位置结点
	  if(p==NULL){
	  	printf("插入位置不合法");
		  exit(1); 
	  } 
	  else{
	  	s=(LinkList)malloc(sizeof(LNode));
	  	s->data=x;
	  	s->next=p->next;
	  	p->next=s;
	  }
   } 

算法时间复杂度为O(n)

4删除运算

(1)删除结点

假设p指向单链表的某一结点,删除p结点的后继结点删除语句如下:

LNode *q=p->next;

p->next=p->next->next;

free(q);

(2)单链表的删除操作

删除单链表第i个位置结点,这就要求查找到第i-1个结点指针p

   void Delete_LinkList(LinkList L,int i){
   	LNode *p,*q;
   	p=Get_LinkList(L,i-1);
   	if(p==NULL)
   	{
   		printf("删除位置不合法");
		   exit(1); 
	   }
	   else{
	   	if(p->next==NULL)
	   	{
	   		printf("删除位置不合法");
			   exit(1); 
		   }
		   else{
		   	q=p->next;
		   	p->next=p->next->next;
		   	free(q);
		   }
	   }
   }

由上面运算,我们得出,在单链表上插入/删除一个结点,必须知道它的前驱结点;单链表不具有按符号随机访问的特点,只能从头指针开始一个个顺序进行。

5求表长运算

   int Length_LinkList(LinkList  L)
   {
   	int l;
   	LNode *p;
   	p=L->next;
   	l=1;
   	while(p->next)
   	{
   		p=p->next;
   		i++;
	   }
	   return 1;
   }

6打印链表

 void print(LinkList L){
   	LNode *p;
   	p=L->next;
   	while(p){
   		printf("%d",p->data);
   		p=p->next;
	   }
   }

7单链表的倒置

算法思路:依次取原链表的每一个节点,总是将其作为新链表当前的第一个节点插入到心链表中

void reverse(LinkList L){
   	LNode *p,*q;
   	p=L->next;
	   L->next=NULL;
	   while(p){
	   	q=p;
	   	p=p->next;
	   	q->next=L->next;
	   L->next=q;
	   } 
   }

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值