数据结构之单链表的实现

果然是写一次就有一次新的发现,防止忘记也忘了刚接触的小伙伴有个头绪特写了这篇单链表的文章。
单链表的概念就不再多说,只实现了相应的基本操作,一切从简,从简单的方式来书写,可能会觉得比较麻烦但思路绝对清晰。
如有错误欢迎指出,相应解释都放在注释里面了。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef struct LinkList{//定义单链表的结构体
	int data;//数据域
	struct LinkList *next;//指针域
}LinkList,*LinkListPtr;//LinkList 结构体,LinkListPtr 结构体指针
void LinkList_Init(LinkListPtr L){//链表的初始化
	L->next = NULL;//其实并没有什么用在写入数据的时候也可以执行这一步
	return;//一切从简,不搞花里胡哨的东西
}
/*void LinkList_Create(LinkListPtr L){//前插法创建链表,顾名思义每次遇到的元素都放在最前面
	int x;
	printf("输入要存储的数据(0结束输入):\n");
	while(1){//死循环 可以一直输入数据
		scanf("%d",&x);
		if(x){
			LinkListPtr p;//这里目的是创建一个结构体,
			p = (LinkListPtr )malloc(sizeof(LinkList));//申请相应大小的内存
			p->data = x;//数据域存储数据
			p->next = L->next;//头插法的写法,看不懂可以画个图,多写几个节点就看懂了
			L->next = p;//继续画图
		}else break;
	}
	return;
}*/
void LinkList_Create(LinkListPtr L){//后插法创建链表,每次元素都放在最后一位
	int x;
	printf("输入要存储的数据(0结束输入):\n");
	LinkListPtr t = L;//需要一个临时变量来暂时代替头指针的作用,后续再代替上一个节点的作用
	while(1){
		scanf("%d",&x);
		if(x){
			LinkListPtr p = (LinkListPtr)malloc(sizeof(LinkList));
			p->data = x;
			p->next = NULL;
			t->next = p;//画图就完事了
			t = p;
		}else break;
	}
	return;
}
void LinkList_Print(LinkListPtr L){//链表的打印
	LinkListPtr p = L->next;
	while(p != NULL){
		printf("%d\t",p->data);
		p = p->next;
	}
	printf("\n");
	return;
}
bool LinkList_GetElem(LinkListPtr L,int pos,int *elem){//获取到某个位置的元素
	int i = 1;//定义一个计数器
	LinkListPtr p = L->next;//指向第一个节点
	while(p != NULL && i <= pos){//位置合法且不是最后一个节点
		if( i== pos){//遍历到了相应的位置就开始取值
			*elem = p->data;
			return true; //还回真,返回的值在主函数中会有作用
		}
		p = p->next;//继续指向下一个节点
		i++;//计数器加一
	}
	return false;//如果一直没有获取到相应的值就返回假
} 
bool LinkList_LocateElem(LinkListPtr L,int elem,int *pos){//获取某个元素在哪个位置
	LinkListPtr p = L->next;//第一个节点
	int i = 1;//计数器
	while(p != NULL){
		if(p->data == elem){//遍历到了开始取其位置
			*pos = i;
			return true;
		}
		p = p->next;//继续指向下一个节点
		i++;//计数器加一
	}
	return false;//如果一直没有获取到相应的值就返回假
}
int LinkList_Length(LinkListPtr L){//求链表的长度
	int len = 0;//计数器
	LinkListPtr p = L->next;
	while(p != NULL){//一直遍历到最后
		len++;
		p = p->next;
	}
	return len;
}
bool LinkList_Insert(LinkListPtr L,int pos,int elem){//在指定位置插入指定元素
	int len = LinkList_Length(L);//先获取到链表当前的长度
	if(pos < 1 || pos > len +1){//判断位置是否合法,插入的位置应该是1<=pos<=len+1,
								//len+1也就是链表的最后位置了
		return false;
	}
	LinkListPtr p = L;//代替头指针的作用
	int i = 1;
	while(1){
		if(pos == i){//如果找到了相应的位置就开始插入
			LinkListPtr t = (LinkListPtr)malloc(sizeof(LinkList));//申请一个新节点来插入进去
			t->data = elem;//保存要插入的数据
			t->next = p->next;//新节点的指针域存放下一个节点的地址
			p->next = t;//上一个节点存放新节点的地址
			return true;
		}
		p = p->next;//找不到就继续往下遍历
		i++;
	}
}
bool LinkList_Delete(LinkListPtr L,int pos){//删除指定位置的元素
	int len = LinkList_Length(L);
	if(pos < 1 || pos > len ){//判断位置是否合法,要删除的位置应该为1<=pos<=len
		return false;
	}
	LinkListPtr p = L;
	LinkListPtr t = L->next;
	int i = 1;
	while(1){
		if(pos == i){
			p->next = t->next;//这样写就可以直接让p指向t的下一个节点
			free(t);//然后再把t释放掉
			return true;
		}
		p = t;
		t = t->next;
		i++;
	}
}
int main(){
	system("color 9F");//看着舒服的颜色
	LinkList L;
	LinkList_Init(&L);
	LinkList_Create(&L);
	LinkList_Print(&L);
	int x;
	int pos;
	
	//以下均为测试 并无其他意义
	if(LinkList_GetElem(&L,5,&x)) printf("要取的元素为%d\n",x);
	else printf("未取到元素请检查pos是否正确!\n");
	
	
	if(LinkList_LocateElem(&L,5,&pos)) printf("要取的元素的位置是%d\n",pos);
	else printf("未查找到该值!\n");
	
	if(LinkList_Insert(&L,6,99)) printf("插入成功!\n");
	else printf("插入失败!\n");
	
	LinkList_Print(&L);
	
	if(LinkList_Delete(&L,6)) printf("删除成功!\n");
	else printf("删除失败!\n");
	
	LinkList_Print(&L);
}

Ps:相应的基本操作已经写的很清晰了,不像书上写的简短而复杂,先理解才是最好的。如有错误请指出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值