数据结构.单链表的各类操作

#include<bits/stdc++.h>
using namespace std;
#define initsize 10
 
//定义一个单链表

/*
	带头结点是为了计算更方便,l头指针没有直接指向需要存储的结点。而不带头结点则直接指向需要实际存储的结点。 
*/
typedef struct lnode
{
	int data;
	lnode *next;
}lnode,*linklist;
/* 
//判断头结点的单链表是否为空 
bool inilist(linklist &l)
{
	l=NULL;
	return true;
}
*/

//带头节点单链表 
bool inilist(linklist &l)//含头结点,l头指针,指向头结点的数据空间,l的next指针,指向空 
{
    if(l==NULL)
    return false;
	l=(lnode*)malloc(sizeof(lnode));//分配一个头节点,lnode表示一个结点而linklist表示整个单链表。 lnode* 相当于 linklist 
	l->next=NULL;   //头指针指向了头结点,因此这里的l->next相当于头结点中的next指针域。 
	return true;
} 
//判断头结点的单链表是否为空 
bool empty(linklist &l) 
{
	if(l->next==NULL)
	return true;
	else
	return false;
}

//按位插入(带头节点)  o(n)
bool listinsert(linklist &l,int i,int e)
{
	if(i<1)   //判断插入位置是否有误 
	{
		return false;
	}
	//找出第i-1的结点 
	lnode* p;   //声明一个头结点 
	p=l;
	int j=0;//表示p所指向的结点 
	while(p!=NULL && j<i-1)//找到第i-1的结点,因此不能<=i-1,应< ,while循环,先判断,再变化。 
	{
		p=p->next;  //每次循环,p结点从头结点,往后移1位。 
		j++;
	}
	
	//创建新节点,进行连接 
	if(p==NULL)
	return false;
	
	lnode* s=(lnode*)malloc(sizeof(lnode));
	s->data=e;//数据域赋值 
	s->next=p->next;
	p->next=s;
	return true;
}
// 按位插入(不带头节点)
bool notouinsert(linklist &l,int i,int e)//无头结点 插入 
{
	if(i==1)    //头处单独处理 
	{
		lnode *s=(lnode*)malloc(sizeof(lnode));  // 
		s->data=e; 
		s->next=l;
		l=s;  //头指针,指向s ,这里l为头指针,没头结点 
		return true;
	}
	lnode *p=l;
	int j=1;
	while(p!=NULL&&j<i-1)
	{
		p=p->next;
		j++;	
	} 
	if(p==NULL)
	return false;
	lnode *s=(lnode*)malloc(sizeof(lnode));
	s->data=e;
	s->next=p->next;
	p->next=s;
	return true;
}
//指定结点后插操作p后插入e  o(1)
bool houcha(lnode *p,int e) 
{
	lnode *s=(lnode*)malloc(sizeof(lnode));//由于直接可以在该节点后插入,所以直接给结点赋值扩展空间
	if(s==NULL)
	return false;
	s->data=e;
	s->next=p->next;  //  crucial  1
	p->next=s;        //  crucial  2
	return true; 
} 

//指定节点——前插操作   o(1)
bool qiancha(lnode *p,lnode *s)
{
	if(p==NULL ||s==NULL)
	return false;
	
	s->next=p->next;  //先后插 
	p->next=s;
	
	int temp =p->data;//然后交换前后数据 
	p->data=s->data;
	s->data=temp;
	return true; 
}

//按位序删除结点(带头结点)  o(n)
bool wei_delete(linklist &l,int i,int &e)//因为e的值需要带回主函数去,所以加个&符号 
{
	if(i<1)
	return false;
    //找第i-1个结点
	lnode* p=l;
	int j=0;
	while(p!=NULL&&j<i-1)
	{
		p=p->next;
		j++;
	}
    //进行排错
	if(p==NULL) //p结点若不存在,则i的位置不对
	return false;
	if(p->next=NULL)//p结点后为结点,则没有要删除的结点
	return false;
	lnode *q=p->next;//q指向p结点的后继结点,即需要删除的结点   crucial q代表要删除得结点 
	e=q->data;       //给删除节点中的数值,赋值给e
	p->next=q->next;//直接把p结点连接到q结点的后继,绕过删除节点,相当于从单链表中剔除掉   crucial 绕过p结点 
	free(q);        //释放q结点
	return true; 
}

//按值删除结点     o(1)
bool zhi_delete(lnode *p)
{
	if(p==NULL)//p结点后为结点,则没有要删除的结点
	return false;
	lnode *q=p->next;//q指向p结点的后继结点,即需要删除的结点   crucial q代表要删除得结点 
	//e=q->data;       //给删除节点中的数值,赋值给e
	p->data=p->next->data;  //  different point
	p->next=q->next;//直接把p结点连接到q结点的后继,绕过删除节点,相当于从单链表中剔除掉   crucial 绕过p结点 
	free(q);        //释放q结点
	return true; 
 } 

//按位查找     o(n) 
lnode * getlist(linklist l,int i)  //我所查找该位置的结点
{
	if(i<0)    //第0个结点为头结点,如果比头结点还靠前,则肯定不对,返回false
	return false;
	lnode *p;  //定义结点指针p指向所需返回的结点
	p=l;       //让p初试位置为头结点处
	int j=0;
	while(p!=NULL && j<i)//因为需要返回第i个位置的结点,所以j<i
	{
		p=p->next;
		j++;
	}
	return p;
} 

//按值查找     o(n) 
lnode *getzhi(linklist &l,int e)
{
	lnode *p=l->next;//直接指向头结点的后继结点,即实际第一个结点
	if(p==NULL)
	return false;
	while(p!=NULL&&p->data!=e)
	{
		p=p->next;
	}
	return p;	
}  
//单链表得长度 o(n) 
int lengthlist(linklist &l)
{
	lnode *p=l;//掐头去尾,去中间,从头结点开始算
	int len=0;
	while(p!=NULL&&p->next!=NULL)//扫描到链尾为止
	{
		p=p->next;
		len++;
	}
	return len;
}  

//头插法建立单链表    crucial apply  链表逆置 
linklist toucreatlist(linklist &l,int &len)
{
	l=(linklist)malloc(sizeof(lnode));    //创建单链表头结点 
	l->next=NULL;
	lnode *s;              
	int x;
	printf("请输入所需添加的数据,输入9999结束输入\n");
	scanf("%d",&x);
	while(x!=9999)
	{
		len++;
		s=(lnode*)malloc(sizeof(lnode));    //创建新的结点,存放数据 
		s->data=x;
		s->next=l->next;
		l->next=s;         //l为头指针  将新结点插入 
		scanf("%d",&x);
	} 
	return l;
}
//尾插法建立单链表   
linklist weicreatlist(linklist &l,int &len)
{
	l=(linklist)malloc(sizeof(lnode));
	l->next=NULL;
	lnode *s;
	lnode *r=l;    //尾定义一个尾指针r,用来表示链表的尾部  让尾指针r=l,就算真正接进l链表中了。
	int x;
	printf("请输入所需添加的数据\n");
	scanf("%d",&x);
	while(x!=9999)
	{	len++;//计算链表长度 
		s=(lnode*)malloc(sizeof(lnode));  //初始化存放数据的结点 
		s->data=x;
		r->next=s;    //r的后继结点指向s 
		r=s;       //指向新的尾部s 
		scanf("%d",&x);	
	} 
	r->next=NULL; 
	return l;
}
int main()
{
	linklist l;//指向单链表的一个指针l,即头指针为l也可写成lnode* l,但是一般lnode表示结点,linklist才表示整个链表 
	inilist(l);//初始化 
	
	return 0;
 } 
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值