数据结构(初学者学习单链表)

链表本质就是在逻辑上连续,在物理内存上不是连续存储的存储数据的方式。链表是由头指针和一个一个节点组成,每个节点会存储一个数据和指向下一个节点的地址(指针),也就是数据域和指针域。

1.单链表(带头结点)

L为头指针(所谓的头指针其实就是头节点的地址),通过这个头指针可以访问到头节点。头节点的数据域没有值,指针域用来存放下一个节点的地址。

定义一个单链表

typedef struct LNode{
	int data;//定义了节点的数据域
	struct LNode *next;//定义了节点的指针域
}LNode,*LinkList;

其中的LNode是struct LNode的别名,LinkList是struct LNode *的别名(其含义为单链表的指针)

初始化单链表

bool InitList(LinkList &L){
	L=(LinkList)malloc(sizeof(LNode));//分配了一个头节点的空间,并把节点的地址赋给了头指针
	if(L==NULL)return 0;//如果头指针为空则分配头节点空间失败
	L->next=NULL;//使头节点的指针域为空,即没有下一个节点
	return 1;
}
int main(){
   LinkList L;//定义一个链表的指针即为头指针
   InitList(L);
}

在链表中插入元素

bool ListInsert(LinkList &L,int i,int e){
	LNode *p,*s;//定义两个LNode型的指针
	int j;
	p=L;//p指针等于头指针
	j=0;//头节点为第0个节点
	while(p&&j<i-1){
		p=p->next;//当j等于i-1时p为第i-1个节点的地址(指针)
		j++;
	}
	if(!p||j>i-1)return falus;//若P为空则超出链表范围
	s=(LinkList)malloc(sizeof(LNode));//分配一个节点的地址
	s->next=p->next;//让s的下一个地址等于p的下一个地址
	s->data=e;//将传入的数据e赋值给s节点的数据域
	p->next=s;//让p指向S
	return true;
	
}

获得链表中的元素

bool GetElem(LinkList L,int i,int &e){
	int j;
	LNode *p;
	p=L->next;//将指针p指向第一个节点(头节点为第0个节点)
	j=1;
	while(p&&j<i){
		p=p->next;//当j等于i时p指向第i个节点
		j++;
	}
	if(!p||j>i) return falus;//若p为空则超出范围
	e=p->data;//将指针p指向的数据域赋值给e
	return true;
}

删除单链表中的元素

bool DeleteList(LinkList &L,int i){
	if(i<1)return 0;//判断删除位置是否合法
	int j=0;//头节点为第0个节点
	LinkList p=L;//将头指针赋值给p
	while(j<i-1){
		p=p->next;//当j等于i-1时跳出循环同时p为第i-1个元素的地址
		j++;
	}
	if((p->next)==NULL)return 0;//判断第i个元素是否存在
	LinkList q=p->next;//将第i个元素的地址赋值给指针变量q
	p->next=q->next;//令第i-1的下一个元素为第i个元素的下一个元素
	free(q);//释放第i个元素的空间
	return 1;		
}

2.单链表(不带头节点)

依然是先定义一个单链表

typedef struct LNode{
	int data;
	struct LNode* next;
}LNode,*LinkList;
向链表中插入一个节点
bool ListInsert(LinkList &L,int i,int e){
	if(i<1)return false;//判断插入位置是否合法
	if(i==1){//当要将插入的节点作为第一个节点时单独判断
		LinkList s=(LinkList)malloc(sizeof(LNode));//分配一个节点的空间并把空间地址给指针s
		s->data=e;//将e赋值给s指向的数据域
		s->next=L;//将头指针的地址赋值给新分配的节点的指针域
		L=s;//将头指针存储的地址变成新分配的节点的地址
        return true;
	}else{//若i!=0
		int j=1;//头指针指向的节点为第一个节点
		LinkList p;//定义一个指针
		p=L;//将头节点的地址赋值给p
		while(p!=NULL&&j<i-1){//若在循环中第j个节点的地址p为空则跳出循环
			p=p->next;
			j++;//循环结束时j=i-1,且p为第i-1个节点的地址
		}
		if(p==NULL)return false;//跳出循环后返回false
		LinkList s=(LinkList)malloc(sizeof(LNode));//分配一个节点的空间把地址赋值给s指针
		if(s==NULL)return false;//判断是否分配空间成功
		else{
			s->data=e;//将e赋值给s对应的数据域
			s->next=p->next;//新节点的下一个节点为原来第i-1个节点的下一个节点
			p->next=s;//将新节点的地址赋值给第i-1个节点的指针域
			return true;
		}	
	}		
}
获取第i个节点的数据域的值
bool GetElem(LinkList L,int i,int &e){
	if(i<1)return false;//判断获取节点的是否合法
	LinkList p;//定义一个指针
	p=L;//将头节点存储的地址赋值给p
	int j=1;//头节点对应的为第1个节点
	while(p!=NULL&&j<i){//判断所获取节点是否超出链表长度
		p=p->next;
		j++;//循环结束时p指针存储的为第i个节点的地址
	}
	if(p==NULL)return false;//若超出范围则报错
	e=p->data;//将第i个节点的数据域的值赋值给e
	return true;
}
删除一个节点 
bool ListDelete(LinkList &L,int i){
	if(i<1)return false;//判断删除是否合法
	int j=1;//头指针对应第一个节点
	LinkList p,q;
	p=L;
	if(i==1){//若删除第一个节点则单独操作
		LinkList s;
		s=L;//将第一个节点的地址赋值给指针s
		L=L->next;//将头指针存储的地址修改为第二个节点的地址
		free(s);//释放掉第一个节点的空间
		return true;	
	}else{//若删除的不是第一个节点
		while(p!=NULL&&j<i-1){//循环的过程中判断时否超出范围
		p=p->next;
		j++;//循环结束时j=i-1,p对应的是第i-1个节点的地址
	    }
    if(p==NULL)return false;//若超出范围则返回错误
	q=p->next;//将第i个节点的地址存储在q中
	p->next=q->next;
//将第i-1个节点的指针域的值修改为第i个节点的指针域的值,也就是第i-1的下一个节点是第i+1个节点
	free(q);//释放第i个节点的空间
	}
	return true;//返回true
}
 更新一个节点的数据域
bool ListUpdata(LinkList &L,int i,int a){
	LinkList p;
	p=L;
	int j=1;
	while(j<i){
		p=p->next;
		j++;//跳出循环时p为第i个节点的地址
	}
	p->data=a;//将第i个节点的数据域的值取为a
	return true;
}
 主函数中的内容如下可以参考
int main(){
	int e;
	LinkList L;
	ListInsert(L,1,5);
	ListInsert(L,2,2);
	ListInsert(L,3,4);
	ListDelete(L,2);
	GetElem(L,2,e);
	printf("%d\n",e);
	ListUpdata(L,1,7);
	GetElem(L,1,e);
	printf("%d",e);
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值