单链表上基本操作的实现——建立,插入,查找,删除,表长。


提示,可以根据目录,可以从 单链表的插入 删除——单链表的查找——单链表的建立这样的顺序进行学习!!!

单链表的建立

单链表的建立主要包括两种建立方法:头插法尾插法
基本步骤如下:

  • 初始化一个单链表
  • 每次取一个数据元素,*插入到表尾/表头 *(导致于头插法,尾插法)

头插法建立单链表

(带头结点的的单链表)
该方法从一个空表开始,生成新结点,并将读取到的数据存放在新结点的数据域中,然后将新结点插入到当前链表的表头,即头结点之后。
本质————是对头结点的后插操作

基本思路
  1. 初始化一个单链表
  2. 利用while循环{每次取一个数据元素e;调用一次后插法——InsertNextNode(L,e)}

代码实现

typedf struct LNode{
   
          //定义单链表结构类型
	ElemType data;         //每个节点存放一个数据元素
	struct LNode *next;    //指针指向下一个节点
}LNode,*LinkList;
//函数功能——头插法建立单链表
LinkList List_HeadInsert(LinkList &L){
   
        //逆向建立单链表
	LNode *s;
	int x;
	L = (LinkList)malloc(sizeof(LNode))    //创建头结点
	L->next=NUll;                          //保证头指针是不会指向脏数据的,初始化为空链表
	scanf("%d",&x);                        //输入结点的值
	
	while(x!=99999){
   
   //只有当输入x为99999时,循环无法进行,否则可以进行————即输入99999代表着结束
		s=(LNode*)malloc(sizeof(LNode)); //申请新结点
		s->data=x;                     //新结点的数据域被x覆盖
		s-next=L->next;                     //将新结点链接在头指针的后继结点
		L->next=s;                          //新结点插入表中,L为头指针
		scanf("d",&x);
	}
	return L;
}

效果:
在这里插入图片描述

问题:若没有头结点,该如何理解头插法的修改?
答:没有了头指针,每次插入新结点后,需要将其指针指向单链表指针L
提示:链表的逆置可以考虑头插法的方法!

尾插法建立单链表

(带头结点的单链表)
法一:

  1. 初始化一个单链表;
  2. 利用按位序插入算法;
  3. 设置变量length来记录链表长度
  4. 每次都要循环,每取一个元素,按位序插入算法用一次,length++,时间复杂度为O( n 2 n^{2} n2)。

法二:
利用后插操作,设置一个表尾指针,每次更新,使得这个指针指向单链表的最后一个结点。

方法原理:

将新结点插入到当前链表的表尾,为此必须增加一个指针,使其始终指向当前链表的尾结点。

代码实现

typedf struct LNode{
   
        //定义单链表结构类型
	ElemType data;        //每个节点存放一个数据元素
	struct LNode *next;    //指针指向下一个节点
}LNode,*LinkList;

//初始化一个空的单链表(带头节点)

bool Initlist(LinkList &L){
   
   
    L = (LNode *)malloc(sizeof(LNode));//分配一个头节点,此头结点不存储数据。
    if(L=NULL)        //内存不足,分配失败
    	return false;
    L->next = MULL;  //头节点之后暂时还没有节点
	return true;
}
//函数:按位序插入,在第i个位置插入元素 e
bool ListInsert(LinkList &L,int i,ElemType e){
   
   
	if(i<1)
		return false;      //插入位置不合法
	LNode *p;              //指针p指向当前扫描的结点;
	int j=0//当前p指向的是第几个结点,利用j来记录;刚开始p指向单链表的头节点;
	P=L;                   //L指向的是头节点,头节点是第0个结点(不存数据)
	while(p!=NULL&&j<i-1){
   
    // 通过循环找到第i-1个结点,这也是本算法的主要的时间开销 :为O(n)
		p=p->next;
		j++;
	}
	if(p==NULL)     //i值不合法,超出链表长度,说明第i-1个结点不存在
		return false;
	LNode *s=(LNode*),malloc(sizeof(LNode));//申请新结点
	s->data=e;                              //在新结点中存入数据元素e
	s->next =p->next;                       //将新结点的指针域发挥与*p的指针域一样的作用:指向第i个结点;
	p->next=s;      //将结点连接到p之后,我们假设的是第i-1个结点为*p;
	return ture;    //插入成功!
}
//函数功能:后插操作,在p结点之后插入元素e.
bool InsertNextNode(LNode *p,ElemType e){
   
   
	if(p==NULL)     //结点p不合法
		return false;
	LNode *s=(LNode*),malloc(sizeof(LNode));//申请新结点
	if(s==NULL)// 内存分配失败   。某些情况有可能分配不足,也可以不考虑这一点
		return false;
	s->data=e;                              //在新结点中存入数据元素e
	s->next =p->next;                       //结点p的下一个结点由新结点s来链接;
	p->next=s;                              //将结点s链接到p之后;
	return ture;                            //插入成功!
}
void test (){
   
    
	LinkList L;  //声明一个指向单链表的指针
	//注意到此处并没有创建一个节点
	//初始化一个空表
	InitList(L);
	//....后续代码。。。。

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值