链表实现细节(个人笔记)

本文章代码实现部分参考自(C语言版)链表(一)——实现单向链表创建、插入、删除等简单操作(包含个人理解说明及注释,新手跟着写代码)



前言

整个C语言课程学习中, 第一个难点是指针数组, 第二个遇到的难点就是链表. 同时在学习数据结构过程中知道链表的原理, 却一直没办法实现. 查找了很多博客, 资料, 有幸看到如上真·新手向 教程, 特此分享并记录自己的不足与理解.


引例1 — 多项式加法

设计函数分别求两个一元多项式的乘积与和。

输入格式:
输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一个多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:
输出1行,以指数递降方式输出和多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。零多项式应输出0 0。

输入样例:
4 3 4 -5 2 6 1 -2 0
3 5 20 -7 4 3 1
输出样例:
5 20 -4 4 -5 2 9 1 -2 0



分析

如果多项式的指数是较为稠密的, 可通过数组来实现. 而如果出现第一项是X的1000次方, 后一项是X的2次方, 如果仍使用数组会出现空间和时间上的极大浪费, 因此选择用链表实现.
实现方式是先将两个多项式以链表的形式创建好, 之后分别从两多项式最高次项(链表头)开始进行比较

  1. 如果A多项式当前指数较大, 将该系数和指数存入答案链表中, 并将A多项式的指针后移一位
  2. 如果B多项式当前指数较大, 将该系数和指数存入答案链表中, 并将B多项式的指针后移一位
  3. 如果两个多项式当前指数相等, 将系数相加,与当前指数存入答案链表中, 并将二者指针后移一位
  4. 当其中一个多项式的指针指向了NULL(链表尾节点), 那么将另一多项式所有后继节点接到答案链表的尾部.


代码实现

#include
#include

/*NODE用来告诉malloc函数该结构体的大小, 而pNODE用来定义新建的链表节点(是一个指向该结构体类型的指针)*/
typedef struct number{
	int x;
	int y;
	struct number *pnext;
}NODE, *pNODE;	



pNODE CreateLink(int n)
{
	/*尾节点只起指向作用, 无需分配空间, 而头节点和临时创建的节点则需要申请空间*/
	pNODE temp = NULL, tail = NULL;		
	pNODE head = (pNODE)malloc(sizeof(NODE));
	
	/*将头节点的后继节点写入NULL,可以检测到链表是否为空*/
	head->pnext = NULL;	
	tail = head;
	
	int i;
	for(i=1; i<=n; i++)
	{
		/*为临时节点申请空间, 并将其后继节点指针指向NULL*/
		temp = (pNODE)malloc(sizeof(NODE));
		scanf("%d %d", &temp->x, &temp->y);
		temp->pnext = NULL;
		
		/*将当前尾结点的后继节点指向temp, 链接起来. 随后将尾结点指向刚刚链接进来的临时节点*/
		tail->pnext = temp;
		tail = temp;
	}
	return head;
}

pNODE AddLink(pNODE head1, pNODE head2)
{
	//创建新的链表, 用于储存相加的结果. 
	pNODE head = (pNODE)malloc(sizeof(NODE));
	head->pnext = NULL;
	
	//定义三个尾节点指针, 用于指向"多项式A","多项式B","和多项式A+B"的当前(末尾)节点
	//对于一个新建的单元,或一个要被删除的单元,最好建立一个临时变量, 因为撤除指针后将不能再引用这个单元. 
	pNODE tail = head, temp = NULL;
	pNODE tail1 = head1->pnext, tail2 = head2->pnext;
	
	
	while(tail1 != NULL && tail2 != NULL)
	{
		
		temp = (pNODE)malloc(sizeof(NODE));
		
		if(tail1->y == tail2->y)	//两子多项式指数相等 
		{
			//若两系数相加不为0, 则将相加后的结果储存到结果链表中; 若为零则跳过储存这步 
			if(tail1->x + tail2->x != 0)
			{
				temp->x = tail1->x + tail2->x;
				temp->y = tail1->y;
				temp->pnext = NULL;
			}			
			tail1 = tail1->pnext;
			tail2 = tail2->pnext;
		}
		else if(tail1->y > tail2->y)	//两子多项式指数不相同时, 指数大者直接链入结果链表中. 
		{
			temp->x = tail1->x;
			temp->y = tail1->y;
			temp->pnext = NULL;
			tail1 = tail1->pnext;
		}
		else
		{
			temp->x = tail2->x;
			temp->y = tail2->y;
			temp->pnext = NULL;
			tail2 = tail2->pnext;
		}
		
		tail->pnext = temp;
		tail = temp;
		
	}
	if(tail1 == NULL)	//某一多项式指向NULL后跳出, 将另一多项式后继节点链入结果链表. 
	{
		tail->pnext = tail2;
	}
	else
	{
		tail->pnext = tail1;
	}
	
	//返回结果多项式头节点. 
	return head;
}




int main(void)
{
	pNODE head1 = (pNODE)malloc(sizeof(NODE));
	pNODE head2 = (pNODE)malloc(sizeof(NODE));
//	NODE head1, head2;		//不是创建结构体, 而是创建拥有所指向结构单元大小的指针. 
	
	head1->pnext = NULL;
	head2->pnext = NULL;
	
	int len_1, len_2;
	scanf("%d", &len_1);
	head1 = CreateLink(len_1);
	scanf("%d", &len_2);
	head2 = CreateLink(len_2);
	
//	printf("in\n");		//仅用于调试 
	pNODE head = AddLink(head1, head2);
//	printf("out\n");	//仅用于调试 
	pNODE tail = head->pnext;
	while(tail!=NULL)
	{
		if(tail == head->pnext)
		{
			printf("%d %d", tail->x, tail->y);
		}
		else
		{
			printf(" %d %d", tail->x, tail->y);
		}
		
		tail = tail->pnext;
	}
	
	return 0;
}

你可能感兴趣的:(学习笔记,数据结构,算法,c语言)