C语言单链表的基本操作总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28584889/article/details/83550172

刷LeedCode时使用单链表频出错误,于是花时间总结了一下单链表的基本操作,把所写代码和详细注释贴在这里,以备后用。

#include <stdio.h>
#include <stdlib.h>

/*定义结构体链表节点:
	该结构体有两个属性,一个是int类型的数据域data,另一个是这个结构体本身类型的指针next;
	最后给这个结构体定义了一个别名Node,一个指针别名pNode;
	Node a; 就等价于struct NODE a; 都是声明一个struct NODE结构体类型的结构体变量a;
	pNode p; 就等价于struct NODE* p; 等价于Node* p; 声明一个struct NODE结构体类型的指针变量p;*/
typedef struct NODE{
	int data;			//数据域
	struct NODE* next;  //指针域,指向下一个节点
}Node, *pNode;

//初始化一个链表节点
pNode init_node(int data)
{
	pNode node = (Node*)malloc(sizeof(Node));
	node->data = data;
	node->next = NULL;	//next为空
	return node;
}

//遍历链表,打印输出每个节点的信息
void traverse_linkList(pNode phead)
{
	pNode ptmp = phead;
	while (ptmp)
	{
		printf("%d  ", ptmp->data);
		ptmp = ptmp->next;
	}
	printf("\n");
}

//头插法插入一个节点
pNode createLink_byHead(pNode phead, int data)
{
	pNode pnode = init_node(data);//首先将准备插入的节点(数据)初始化为一个新的链表节点

	if(NULL == phead)//如果插入前的链表为空,则返回当前的新节点
		return pnode;
	else{
		pnode->next = phead;
		return pnode;
	}
}

//尾插法插入一个节点
pNode createLink_byTail(pNode phead, int data)
{
	pNode pnode = init_node(data);//首先将准备插入的节点(数据)初始化为一个新的链表节点
	pNode ptail =phead;//用于标记链表的尾节点,初始时为头结点

	if(NULL == phead)
		return pnode;//如果插入前的链表为空,则返回当前的新节点
	else{
		while (ptail->next)
		{
			ptail = ptail->next;
		}//从头到尾遍历整个链表找到最后的尾节点
		ptail->next = pnode;//将新的节点插入到最后
		return phead;
	}
}

//使用头插法或者尾插法建立一条单链表
pNode createSingleList(pNode phead)
{
	int data, len;
	pNode temp;
	printf("请输入建立的链表节点个数:");
	scanf("%d", &len);
	for (int index = 0; index < len; index++)
	{
		printf("请输入第 %d 个节点的数值:", index + 1);
		scanf("%d", &data);
		//phead = createLink_byHead(phead, data);//使用头插法建立链表
		phead = createLink_byTail(phead, data);//使用尾插法将建立链表
	}
	//打印输出链表中每一个节点
	traverse_linkList(phead);
	return phead;
}

//求链表的长度
int lengthofLinklist(pNode phead)
{
	int len = 0;
	pNode ptmp = phead;
	while (ptmp)
	{
		len++;
		ptmp = ptmp->next;
	}
	return len;
}

//按值查找(查找链表中等于某一数值的节点并返回,如果有多个则返回最前面的,如果没有则返回空)
pNode searchLinklist_byValue(pNode phead, int val)
{
	pNode ptmp = phead;

	if(NULL == phead)
		return NULL;
	while (ptmp)
	{
		if(ptmp->data == val)
			return ptmp;
		ptmp = ptmp->next;
	}
	return NULL;
}

//前插法(将新节点插入到与val值相等的第一个链表节点的前面)
pNode insertNode_fromPrev(pNode phead, int data, int val)
{
	pNode pnew = init_node(data);//初始化新插入的节点
	pNode ptmp = phead;

	if(NULL == phead)//链表为空,直接返回新的节点
		return pnew;
	else if(phead->data == val){ //头节点是否为目标节点
		pnew->next = phead;
		return pnew;
	}else{
		while (NULL != ptmp->next && ptmp->next->data != val)
			ptmp = ptmp->next;
		if(NULL == ptmp->next)//没找到
		{
			printf("insert value not found\n");
		}else{ //找到了,把新节点插入到目标节点的前面
			pnew->next = ptmp->next;
			ptmp->next = pnew;
		}
	}
	return phead;
}

//后插法(将新节点插入到与val值相等的第一个链表节点的后面)
pNode insertNode_fromRear(pNode phead, int data, int val)
{
	pNode pnew = init_node(data);//初始化新插入的节点

	if(NULL == phead)//链表为空,直接返回新的节点
		return pnew;
    pNode ptmp = searchLinklist_byValue(phead, val);//调用按值查找函数
	if (NULL == ptmp)//没有找到
		printf("insert value not found\n");
	if(NULL == ptmp->next)//如果目标节点为最后一个节点
		ptmp->next = pnew;
	else{ //将新节点插入到目标节点后面
		pnew->next = ptmp->next;
		ptmp->next = pnew;
	}
	return phead;
}

//删除节点(删除链表中所有等于val的节点)
pNode deleteNode(pNode phead, int val)
{
	pNode ptmp = phead;
	pNode pdel = NULL;
	if(NULL == phead)//链表为空
	{
		printf("Linklist is empty,delete fail!\n");
		return phead;
	}else if(phead->data == val)//删除头结点
	{
		phead = phead->next;
		free(ptmp);
		ptmp = NULL;
	}else{
		while (NULL != ptmp->next && ptmp->next->data != val)
		{
			ptmp = ptmp->next;
		}
		if(NULL == ptmp->next)//找不到
		{
			printf("delete value is not found, delete fail!\n");
		}else if(ptmp->next->data == val){ //找到目标点(包括删除的节点是尾节点的情况)
			pdel = ptmp->next;
			ptmp->next = pdel->next;
			free(pdel);
			pdel = NULL;
		}
	}
	return phead;
}

int main()
{
	pNode phead, p;
	phead = NULL;
	phead = createSingleList(phead);//从无到有建立一条单链表,返回的phead是这条链表的头指针
	int len = lengthofLinklist(phead);
	printf("链表的长度为:%d\n", len);

	//phead = insertNode_fromPrev(phead, 100, 10);
	//phead = insertNode_fromRear(phead, 100, 10);
	phead = deleteNode(phead, 100); 
	traverse_linkList(phead);
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_28584889/article/details/83550172