单链表的基本运算

单链表的基本运算

1.单链表的定义
链表是通过一组地址任意的存储单元来存储线性表中的数据元素,这些存储单元可以是连续的,也可以是不连续的。
链表是线性结构 每个元素有且仅有一个直接前驱和2直接后驱(a1只有后驱,an只有前驱)
单链表结点结构
| data | next |

单链表一般都有头指针head,只要知道了头指针,就可以找到链表的所有结点。

通常为了方便实现链表的各种运算,在单链表的第一个节点之前附设一个类型相同的结点,该结点成为头节点

2.单链表的基本运算

2.1单链表的结构类型定义

`typedef int elemtype //定义结点的数据类型
typedef struct node //定义单链表结点
{
elemtype data;
sruct node *next;
}LinkList;
LinkList *head; //定义头指针

2.2单链表的基本运算
单链表的基本运算包括:链表的建立,求表长,查找,插入,删除,遍历,及置空表等。

2.21单链表的建立
(1)头插法
算法的基本思想是:首先生成一个新结点,将读入的数据存入新结点数据域,然后将新结点x作为第一个结点插入到链表的头结点之后,重复,直到输入结束。

LinkList *Create_LinkList()
{
  elemtype ix; //结点的值
  Linklist *head,*p;  //定义头节点和结点p
  head=(LinkList *)malloc(sizeof(LinkList);
  if(head==NULL)
   return head;
  head->next=NULL;//将头指针初始化
  printf("请输入数据直到输入0结束\n");
  scanf("%d",&x);
  while(x!=0)
  {
  p=(LinkList *)mallo(sizeof(LinkList));
  if(p==NUll) //p结点申请失败
  return head;
  p->data=x;  //为p结点数据域赋值
  p->next=head->next;//将p指向head的下一个指针
  head->next=p;//将新结点p连接在头结点之后
  scanf("%d",&x);
  }
  return head;
  }

头插法就是将新生成的元素放在头结点之后,所以后面输入的数据会放在前面。

(2)尾插法

基本思想:生成一个新结点,将新结点连入到当前链表的尾结点之后,重复。

LinkList * Create_LinkListR()
{
  elemtype x;
  LinkList *head,*p,*tail;
  head=(LinkList*) malloc(sizeof(LinkList));
  if(head==NULL)
   return head;
  head->next=NULL;//将头指针初始化
  printf("请输入数据直到输入0结束\n");
  scanf("%d",&x);
  while(x!=0)
  {
  	 p=(LinkList *)mallo(sizeof(LinkList));
 	 if(p==NUll) //p结点申请失败
 	 return head;
 	 p->data=x;  //为新结点数据域赋值
	tail->next=p;//将新结点接在tail指针之后
	tail->p;   //将tail指针移到新结点
	tail->next=NULL;  //将tail指针初始化
	scanf("%d",&ix);
	}
	return head;
}

两个算法的时间复杂度都为O(n)

2.3单链表的遍历
基本思想:设一个移动指针,从首结点开始依次访问链表中的每个结点,同时输出数据,直到尾结点

int Print_LinkList(LinkList *head)
{	LinkList *p=head->next;
	if(p)	//链表为空,返回值为零
		return 0;
	while(!p)
	{
		printf("%d",p->data);//输出当前结点的数据
		p=p->next;  //移动指针到下一个结点
	}
	return 1;
}

2.4求单链表的长度
基本思想:设置一个移动指针和计数器,从首结点开始扫描到尾结点,每扫描到一个结点,计算器加1,直到结束。

int LinkList_Length(LinkList *head)
{	LinkList *p=head;  
	int j=0;
	if(p-next!=NULL)  //只需要看下一个结点存不存在,存在时移动指针才能往下一移动,计数器才能加1
	{	p=p->next;
		j++;
	}
	return j;
}

2.5单链表的查找
链表相邻的结点并未存储在物理相邻的存储单元里,不能像顺序表那样直接查找,只能从头指针开始,沿着链一直查找。
(1)按序号查找
和求长度大同小异,设置计数器和移动指针
同时要考虑序号是否有效

LinkList *GetData_LinkList(LinkList *head,int i)
{	LinkList *p;
	int j=0;
	if(i<1)
	return NULL;
	p=head;
	while(p->next!=NULL&&j<i) //链表遍历完或者没有找到这个序号的时候退出循环
	{	p=p->next;
		j++;
	}
	if(i==j)	return p;
	else return NULL;

(2)按值查找
基本思想:将每个结点与指定关键字中的值进行比较。

LinkList *Search_LinkList(LinkList*head,elemtype key)
{	LinkList *p;
	p=head->next;
	while(!p)
    {
    if(p->next!=key)
    	p=p->next;
    else break;
    }
   return p;
 }
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值