链表的增删查改

链表的插入

    头插法:

    尾插法:

有序插入:

#include <stdio.h>
#include <stdlib.h>
//头插法 输入:4 5 10 2 6 8  输出:8 6 2 10 5 4
typedef struct student {
	int num;
	struct student *pNext;
}Student_t,*pStudent_t; //struct student* 

void listHeadInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listTailInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listSortInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listPrint(pStudent_t pHead);

int main(){
	pStudent_t phead = NULL, ptail = NULL;//头指针,尾指针
	int num;
	while (scanf("%d", &num) != EOF)
	{
		//listHeadInsert(&phead, &ptail, num);//插入新节点,头尾指针都要改变,
		                    //故对头尾指针操作要取地址
		//listTailInsert(&phead, &ptail, num);
		 listSortInsert(&phead, &ptail, num);
	}
	listPrint(phead);//值传递,没有去地址,不会改变这个值

}

//头插法  插进去的变成头?
void listHeadInsert(pStudent_t *ppHead, Student_t **ppTail, int val)//??理解一下这里面的参数
{
	pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));//申请空间 
	pNew->num = val;
	if (NULL == *ppHead)//判断链表是否为空
	{
		*ppHead = pNew;//新节点既给头节点,又给尾节点 
		*ppTail = pNew;
	}
	else {
		pNew->pNext = *ppHead;//对ppHead取值才是一级指针才能拿到外面的值???
		*ppHead = pNew;
	}
}

//尾插法  输出和输出顺序一致,尾插,即新节点变成尾
void listTailInsert(pStudent_t *ppHead, Student_t **ppTail, int val)//??理解一下这里面的参数
{
	pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));//申请空间 
	pNew->num = val;
	if (NULL == *ppTail)//判断链表是否为空,用NULL==*ppHead也可以
	{
		*ppHead = pNew;//新节点既给头节点,又给尾节点 
		*ppTail = pNew;
	}
	else {
		(*ppTail)->pNext=pNew;//对ppHead取值才是一级指针才能拿到外面的值???
		                    //二级指针拿到一级指针才可以进行成员访问
		*ppHead = pNew;
	}
}

//有序插入   ????????这个比较复杂 输入3 6 9 3 7 -5 20
                 //输出-5 3 3 6 7 9 10 20
void listSortInsert(pStudent_t *ppHead, Student_t **ppTail, int val)
{//按从小到大 比如说 2 3 6之间插一个数
	pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));
	pStudent_t pCur = *ppHead,pPre;//这个需要理解一下????
	//pPre相当于pStudent_t pPre;?????
	pCur = pPre = *ppHead;//最开始都指向第一个节点(头节点),初始化,为了执行下面,介于头尾之间的情况
	pNew->num = val;
	if (NULL == *ppHead) {//*ppHead可以改成pCur 判断链表是否为空
		*ppHead = pNew;//这里不能换成pCur
		*ppTail = pNew;
	}else if (val < pCur->num){ //小于头部节点,如1,即,插进去了变成头,头插法
		pNew->pNext = *ppHead;//这里可以换成pCur
		*ppHead = pNew;//但这里不可以换成pCur,要改变最初的那个
	}
	else{//插入的介于头尾节点之间,如4
		while (pCur) {//插入到中间
			           //两个指针这里
			if (pCur->num > val)//pCur所指的值大于要插入的值时
			{//如果pCur->val大于插入的值时,执行这一句
				pPre->pNext = pNew;
				pNew->pNext = pCur;
				break;
			}
			//如果pCur->num<val的值时,执行下面两句
			pPre = pCur;//小弟先保存大哥的位置
			pCur = pCur->pNext;
		}
		if (NULL == pCur)//大于尾节点的值,如8,要插入到尾部
		{//尾插法
			(*ppTail)->pNext = pNew;//这里的(*ppTail)->pNext等价于pPre->pNext
			*ppTail = pNew;
		}
	}

}

void listPrint(pStudent_t pHead)
{
	while (pHead != NULL)//打印,遍历,while循环
	{
		printf("%d", pHead->num);
		pHead = pHead->pNext;
	}
	printf("\n");
}

链表的增删查改

#include <stdio.h>
#include <stdlib.h>
//头插法 输入:4 5 10 2 6 8  输出:8 6 2 10 5 4
typedef struct student {
	int num;
	float score;
	struct student *pNext;
}Student_t, *pStudent_t; //struct student* 

void listHeadInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listTailInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listSortInsert(pStudent_t *ppHead, Student_t **ppTail, int val);
void listDelete(pStudent_t *ppHead, Student_t **ppTail, int val);
void listModify(pStudent_t pHead, int num, float score);
void listPrint(pStudent_t pHead);

int main() {
	pStudent_t phead = NULL, ptail = NULL;//头指针,尾指针
	int num;
	float score;
	while (scanf("%d", &num) != EOF)
	{
		// listHeadInsert(&phead, &ptail, num);//插入新节点,头尾指针都要改变,
							//故对头尾指针操作要取地址
		//listTailInsert(&phead, &ptail, num);
		listSortInsert(&phead, &ptail, num);
	}
	listPrint(phead);//值传递,没有去地址,不会改变这个值
	/*while (printf("please input delete num: "), fflush(stdout), scanf("%d", &num) != EOF)
	{
		listDelete(&phead, &ptail, num);
		listPrint(phead);
	}*/
	while (printf("please input modify num and score:"), fflush(stdout), scanf("%d%f", &num,&score) != EOF)
	{
		listModify(phead, num, score);
		listPrint(phead);
	}
}

//头插法  插进去的新元素变成头?
void listHeadInsert(pStudent_t *ppHead, Student_t **ppTail, int val)//??理解一下这里面的参数
{
	pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));//申请空间 
	pNew->num = val;
	if (NULL == *ppHead)//判断链表是否为空
	{
		*ppHead = pNew;//新节点既给头节点,又给尾节点 
		*ppTail = pNew;
	}
	else {
		pNew->pNext = *ppHead;//对ppHead取值才是一级指针才能拿到外面的值???
		*ppHead = pNew;
	}
}

//尾插法  输出和输出顺序一致,尾插,即新节点变成尾
void listTailInsert(pStudent_t *ppHead, Student_t **ppTail, int val)//??理解一下这里面的参数
{
	pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));//申请空间 
	pNew->num = val;
	if (NULL == *ppTail)//判断链表是否为空,用NULL==*ppHead也可以
	{
		*ppHead = pNew;//新节点既给头节点,又给尾节点 
		*ppTail = pNew;
	}
	else {
		(*ppTail)->pNext = pNew;//对ppHead取值才是一级指针才能拿到外面的值???
							//二级指针拿到一级指针才可以进行成员访问
		*ppHead = pNew;
	}
}

//有序插入   ????????这个比较复杂 输入3 6 9 3 7 -5 20
				 //输出-5 3 3 6 7 9 10 20
void listSortInsert(pStudent_t *ppHead, Student_t **ppTail, int val)
{//按从小到大 比如说 2 3 6之间插一个数
	pStudent_t pNew = (pStudent_t)calloc(1, sizeof(Student_t));
	pStudent_t pCur = *ppHead, pPre;//这个需要理解一下????
	//pPre相当于pStudent_t pPre;?????
	pCur = pPre = *ppHead;//最开始都指向第一个节点(头节点),初始化,为了执行下面,介于头尾之间的情况
	pNew->num = val;
	if (NULL == *ppHead) {//*ppHead可以改成pCur 判断链表是否为空
		*ppHead = pNew;//这里不能换成pCur
		*ppTail = pNew;
	}
	else if (val < pCur->num) { //小于头部节点,如1,即,插进去了变成头,头插法
		pNew->pNext = *ppHead;//这里可以换成pCur
		*ppHead = pNew;//但这里不可以换成pCur,要改变最初的那个
	}
	else {//插入的介于头尾节点之间,如4
		while (pCur) {//插入到中间
					   //两个指针这里
			if (pCur->num > val)//pCur所指的值大于要插入的值时
			{//如果pCur->val大于插入的值时,执行这一句
				pPre->pNext = pNew;
				pNew->pNext = pCur;
				break;
			}
			//如果pCur->num<val的值时,执行下面两句
			pPre = pCur;//小弟先保存大哥的位置
			pCur = pCur->pNext;
		}
		if (NULL == pCur)//大于尾节点的值,如8,要插入到尾部
		{//尾插法
			(*ppTail)->pNext = pNew;//这里的(*ppTail)->pNext等价于pPre->pNext
			*ppTail = pNew;
		}
	}

}

//删除
void listDelete(pStudent_t *ppHead, Student_t **ppTail, int deleteNum)
{
	pStudent_t pCur = *ppHead, pPre;
	pPre = pCur;
	if (NULL == pCur)//链表的删除之前要判断是否为空链表
	{
		printf("查不到这个结点\n");//空的话不能删除,否则有问题
		return;
	}
	else if (pCur->num == deleteNum)//删除的是头节点的话,即要删除节点的值等于deleteNum
	{
		*ppHead = pCur->pNext;//改变头指针,指向下一个节点
		if (NULL == *ppHead)//但是如果删除的时候只有一个节点时
		{//即删除后,头尾指针皆为NULL
			*ppTail = NULL;
		}
	}
	else {//删除的时中间或者尾部
		while (pCur != NULL)
		{
			if (pCur->num == deleteNum)//如果pCur->num等于要删除的值时
			{
				pPre->pNext = pCur->pNext;
				break;
			}
			pPre = pCur;
			pCur = pCur->pNext;
		}
		if (NULL == pCur)//如果没有找到对应的节点的话
		{
			printf("没有找到这个要删除的数字\n");
			return;
		}
		if (pCur == *ppTail)
		{
			*ppTail =pPre;
		}
	}
	free(pCur);
	pCur = NULL;
}

//链表的修改
void listModify(pStudent_t pHead, int num, float score)
{
	while (pHead)
	{
		if (pHead->num == num)
		{
			pHead->score = score;
			break;
		}
		pHead = pHead->pNext;
	}
	if (NULL == pHead)
	{
		printf("没有这个值\n");
	}
}

void listPrint(pStudent_t pHead)
{
	while (pHead != NULL)//打印,遍历,while循环
	{
		printf("%3d %5.2f\n", pHead->num,pHead->score);
		pHead = pHead->pNext;
	}
	printf("\n");
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值