双链表的增删查改(C语言)

//主题:双向链表
//功能:分别实链表的插入、删除、查找操作
//提示:如果需要进入下一步操作,输入3个ctrl z即可

#define _CRT_SECURE_NO_WARNINGS
#include
#include
typedef struct student
{
	int num;
	float score;
	struct student *pnext;
	struct student *ppre;
}stu, *pstu;

//打印
void list_print(pstu phead, pstu ptail)
{
	pstu pcur = phead;
	printf("顺序打印:\n");
	while (pcur != NULL)
	{
		printf("%d %2.2f\n", pcur->num, pcur->score);
		pcur = pcur->pnext;
	}
	printf("\n");

	printf("逆序打印:\n");
	pcur = ptail;
	while (pcur != NULL)
	{
		printf("%d %2.2f\n", pcur->num, pcur->score);
		pcur = pcur->ppre;
	}
	printf("\n");
}

//增:头插法(插在左边)
void list_insert_head(pstu *pphead, pstu *pptail, int i)
{
	pstu pnew;
	pnew = (pstu)calloc(1, sizeof(stu));
	pnew->num = i;
	if (NULL == *pptail)//如果链表为空
	{
		*pphead = pnew;
		*pptail = pnew;//不用担心尾节点不是NULL,因为calloc的pnew中的pnext成员本身就是null
	}
	else//如果链表非空
	{
		pnew->pnext = *pphead;//新节点的pnext成员指向原有链表头
		(*pphead)->ppre = pnew;//新节点的ppre指向原有链表头
		*pphead = pnew;//新节点成为新的链表头
	}
}

//增:尾插法
void list_insert_tail(pstu *pphead, pstu *pptail, int i)
{
	pstu pnew;
	pnew = (pstu)calloc(1, sizeof(stu));
	pnew->num = i;
	if (NULL == *pptail)//如果链表为空
	{
		*pphead = pnew;
		*pptail = pnew;//不用担心尾节点不是NULL,因为calloc的pnew中的pnext成员本身就是null
	}
	else
	{
		(*pptail)->pnext = pnew;//原有链表尾的pnext成员指向新节点
		pnew->ppre = *pptail;//新节点的ppre指向原有链表尾
		*pptail = pnew;//新节点成为新的链表尾
	}
}

//增:有序插入
void list_insert_sort(pstu *pphead, pstu *pptail, int i)
{
	pstu pnew;
	pnew = (pstu)calloc(1, sizeof(stu));
	pnew->num = i;
	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	if (NULL == *pptail)//如果链表为空
	{
		*pphead = pnew;
		*pptail = pnew;//不用担心尾节点不是NULL,因为calloc的pnew中的pnext成员本身就是null
	}
	else
	{
		//从小到大
		if (i <= pcur->num)//如果小于第一个节点,头插
		{
			pnew->pnext = *pphead;//新节点的pnext成员指向原有链表头
			(*pphead)->ppre = pnew;//新节点的ppre指向原有链表头
			*pphead = pnew;//新节点成为新的链表头
			return;
		}
		else//向后遍历
		{
			while (NULL != pcur)//只要不是最后
			{
				if (i <= pcur->num)//找到插入的位置
				{
					pbefore->pnext = pnew;//小弟的pnext成员指向新节点
					pnew->ppre = pbefore;//新节点的ppre成员指向pbefore
					pnew->pnext = pcur;//新节点的pnext成员指向大哥
					pcur->ppre = pnew;//大哥的ppre成员指向新节点
					break;
				}
				pbefore = pcur;//小弟记住大哥的脚印
				pcur = pcur->pnext;//大哥先走一步		
			}
			if (NULL == pcur)//如果到最后,尾插
			{
				(*pptail)->pnext = pnew;//原有链表尾的pnext成员指向新节点
				pnew->ppre = *pptail;//新节点的ppre成员指向原有链表尾
				*pptail = pnew;//新节点成为新的链表尾
			}
		}
	}
}

//删除
void list_delete(pstu *pphead, pstu *pptail, int i)
{
	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	if (NULL == *pptail)//如果链表为空
	{
		printf("链表为空\n");
	}
	else if (i == (*pphead)->num)//如果要删除第一个节点(此时可能仅剩一个节点)
	{
		(*pphead)->pnext->ppre = (*pphead)->ppre;//下一个节点的ppre指向原有头节点的ppre(=NULL)
		*pphead = (*pphead)->pnext;//头指针指向下一个节点
		free(pcur);//释放原有头节点的内存
		if (NULL == *pphead)//如果删除后链表为空
		{
			*pptail = NULL;
		}
	}
	else//如果不等于第一个节点
	{
		while (NULL != pcur)//如果pcur没有走出最后一个节点
		{
			if (i == pcur->num)//如果等于当前节点
			{
				pcur = pcur->pnext;//大哥前进一步
				pbefore->pnext = pcur;//小弟的pnext成员指向大哥
				pcur->ppre = pbefore;//大哥的ppre成员指向小弟
				return;
			}
			else
			{
				pbefore = pcur;//小弟记住大哥的脚印
				pcur = pcur->pnext;//大哥先走一步		
			}
		}
		if (NULL == pcur)//如果到最后
		{
			printf("不存在此数字\n");
		}
	}
}

//修改
void list_modify(pstu *pphead, pstu *pptail, int i, float score)
{
	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	if (NULL == *pptail)//如果链表为空
	{
		printf("链表为空\n");
	}
	else
	{
		while (NULL != pcur)//只要不是最后
		{
			if (i == pcur->num)//如果等于当前节点,修改
			{
				pcur->score = score;
				return;
			}
			else
			{
				pbefore = pcur;//小弟记住大哥的脚印
				pcur = pcur->pnext;//大哥先走一步		
			}
		}
		if (NULL == pcur)//如果到最后
		{
			printf("不存在此数字\n");
		}
	}
}

//查找
void list_find(pstu *pphead, pstu *pptail, int i)
{
	pstu pcur = *pphead;
	pstu pbefore = *pphead;
	if (NULL == *pptail)//如果链表为空
	{
		printf("链表为空\n");
	}
	else
	{
		while (NULL != pcur)//只要不是最后
		{
			if (i == pcur->num)//如果等于当前节点,输出
			{
				printf("查询成功:\n%d %2.2f\n", i, pcur->score);
				return;
			}
			else
			{
				pbefore = pcur;//小弟记住大哥的脚印
				pcur = pcur->pnext;//大哥先走一步		
			}
		}
		if (NULL == pcur)//如果到最后
		{
			printf("不存在此数字\n");
		}
	}
}

int main()
{
	int i;
	float score;
	pstu phead = NULL;
	pstu ptail = NULL;
	//增
	printf("请输入你要插入的数字:");
	while (scanf("%d", &i) != EOF)
	{
		list_insert_head(&phead, &ptail, i);//头插法
		//list_insert_tail(&phead, &ptail, i);//尾插法
		//list_insert_sort(&phead, &ptail, i);//有序插入
	}
	list_print(phead, ptail);

	//删
	printf("请输入你要删除的数字:");
	while (scanf("%d", &i) != EOF)
	{
		list_delete(&phead, &ptail, i);
		printf("输出:\n");
		list_print(phead, ptail);
	}

	//改	
	printf("请输入你要修改的序号和数字:");
	while (scanf("%d %f", &i, &score) != EOF)
	{
		list_modify(&phead, &ptail, i, score);
		printf("输出:\n");
		list_print(phead, ptail);
	}

	//查
	printf("请输入你要查找的序号:");
	while (scanf("%d", &i) != EOF)
	{
		list_find(&phead, &ptail, i);
	}
	system("pause");
}

你可能感兴趣的:(c语言,链表,数据结构)