链表操作总结

参考链接: https://blog.csdn.net/men_wen/article/details/52877331
总结一下链表的基本操作,若有问题,欢迎讨论

1、基本概念

链表是一中常见的数据结构,通过一组任意的存储单元来存储线性表中的数据元素,这些存储单元可以是连续的也可以是不连续的,主要包含数据域(用于存储节点数据)和指针域(用于存储下一个指向节点的指针),结构如下:

typedef struct node{
	int data;
	struct node *next;
} NODE;

指针域中存储的是下一个节点的地址值
数据域存储的是这个节点保存的值
举个例子,大家将就看一下

指针操作解读:

int var = 1;
int *p = &var;
// p变量中存储的值,值为var的地址
printf("%d, %d", p, &var);
// *可以读为指向的地址存储的值, 所以*p读为p指向的地址存储的值,值为var的值
printf("%d, %d", *p, var);
// &读为取地址,所以&p为取p的地址值,值为p的地址
printf("%d, %d", &p);

2、创建节点

NODE *initNode(NODE *pnode, int data){
	pnode = (NODE *)malloc(sizeof(NODE));
	pnode->data = data;
	pnode->next = NULL;

	return pnode;
}

3、创建链

前插法

将新节点放在链表头

//创建链(前插法)
NODE * createNodeList_bytail(NODE *phead, int data){
	NODE *pnode = initNode(pnode, data);
	NODE *ptmp = phead;
	if(NULL == phead){
		return pnode;
	} else {
		while(ptmp->next != NULL){
			ptmp = ptmp->next;
		}

		ptmp->next = pnode;
	}

	return phead;
}

尾插法

将新节点放在链表尾

//创建链(尾插法)
NODE * createNodeList_byhead(NODE *phead, int data){
	NODE *pnode = initNode(pnode, data);
	NODE *ptmp = phead;
	if(NULL == phead){
		return pnode;
	} else {
		phead = pnode;
		phead->next = ptmp;
	}

	return phead;
}

4、释放链

NODE * destroylist(NODE *phead){
	NODE * tmp = NULL;
	while(phead != NULL){
		tmp = phead;
		phead = phead->next;

		free(tmp);
		tmp = NULL;
	}
}

5、链表长度

int listlen(NODE *phead){
	int len = 0;
	if(phead == NULL){
		return len;
	} else {
		while(NULL != phead){
			len++;
			phead = phead->next;
			
		}
		return len;
	}
}

6、遍历输出链表

void traversalList(NODE * phead){
	int i = 0;

	while(phead != NULL){
		printf("%d, %d\n", ++i, phead->data);
		phead = phead->next;
	}
}

7、插入节点

前插节点

将新节点插入在被插入节点之前

NODE * insertNode_byhead(NODE *phead, int key, int data){
	NODE *pnode = initNode(NULL, data);
	NODE *ptmp = phead;

	if (ptmp == NULL) {
		return pnode;
	}

	if (ptmp->data == key) {
		phead = pnode;
		phead->next = ptmp;
	} else
	{
		while(ptmp->next != NULL && ptmp->next->data != key){
			ptmp = ptmp->next;
		}
		if (ptmp->next == NULL) {
			printf("key not found\n");
		} else
		{
			pnode->next = ptmp->next;
			ptmp->next = pnode;
		}

		return phead;
	}	
}

后插节点

将新节点插入在被插入节点之前

NODE * insertNode_bytail(NODE *phead, int key, int data){
	NODE *pnode = initNode(NULL, data);
	NODE *ptmp = findnode(phead, key);

	if(ptmp == NULL){
		printf("key not found\n");
	} else
	{
		if (ptmp->next == NULL) {
			ptmp->next = pnode;
		}else
		{
			pnode->next = ptmp->next;
			ptmp->next = pnode;
		}
	}

	return phead;
}

8、按值查找节点

NODE * findnode(NODE *p, int value){
	if(NULL == p){    //链表为空,直接返回
		return NULL;
	}

	while(p != NULL && p->data != value){
		p = p->next;
	}
	if (p == NULL) {
		return NULL;
	} else
	{
		return p;
	}
}

9、删除节点

NODE *deleteNode(NODE *phead, int key){
	NODE *ptmp = phead;

	if (ptmp == NULL) {
		printf("key not found\n");
		return NULL;
	}

	if (ptmp->data == key) {
		phead = phead->next;
		free(ptmp);
		ptmp = NULL;
	} else`在这里插入代码片`
	{
		while(ptmp->next != NULL && ptmp->next->data != key){
			ptmp = ptmp->next;
		}
		if (ptmp->next == NULL) {
			printf("key not found\n");
		} else
		{
			NODE *p = ptmp->next;
			ptmp->next = p->next;
			free(p);
			p = NULL;
		}

		return phead;
	}
}

10、链表倒置

NODE * reverselist(NODE *phead){
	NODE *pre = NULL;
	NODE * tmp = NULL;
	if (phead == NULL) {
		printf("phead is NULL\n");
		return NULL;
	}
	
	if (phead->next == NULL) {
		return phead;
	}

	while(phead != NULL){
		tmp = phead;
		phead = phead->next;
		
		tmp->next = pre;
		pre = tmp;
	}
	
	return pre;
}

曾经在链表倒置这里迷糊过,倒置之后只是把每个节点的指针域的值改为了前一个节点,而节点本身所处位置的值并没有改变

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值