`

重学数据结构001——链表基本操作与一元多项式相加(C语言)

阅读更多

        大一的时候我们专业开了一门C语言限选课,老师觉得指针太难,所以不讲指针。大三的时候学数据结构,考虑到数据结构比较难,老师不要求代码实现。就这样,两门比较重要的课就这样浑浑噩噩的过去了。后来学Java,算是学的还行,也独立的做过一些导师的项目。只是在找工作的时候,才发现笔试题、面试题到处都是C、C++和数据结构的题。多多少少也因此碰了不少壁。不管怎么样,自己还年轻,以前没学好,现在学也不晚。

        这一系列博客,我会分别用Java和C实现一些数据结构基本操作以及书中提到的问题。一方面算是巩固Java,另一方面算是重新学习数据结构和C语言吧。

        教材:《数据结构与算法分析——C语言描述》(第二版)(Mark Allen Weiss著,冯舜玺译)(机械工业出版社)。


1.链表的基本操作

        链表数据结构的定义:由于链表一方面需要在节点中存储数据,另一方面还需要存储"线索",因此,通常采用结构体定义链表节点数据类型。

 

struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
typedef int ElementType;
struct Node 
{
	ElementType Element;
	Position Next;
};

        链表的操作不算太多,下面是一些常用的操作:

 

//创建链表
List CreateList();
//遍历链表
void TraverseList(List L);
//清空链表
List MakeEmpty(List L);
//判断给定列表是否为空
int IsEmpty(List L);
//判断节点在给定链表中是否为空
int IsLast(Position P, List L);
//在指定的链表中查找给定元素。
//存在则返回其第一次出现的位置,不存在则返回NULL
Position Find(ElementType X, List L);
//删除链表中的某个元素
void Delete(ElementType X, List L);
//在指定链表中查找给定元素的前驱节点
Position FindPrevious(ElementType X, List L);
//在链表给定位置的后面插入元素
void Insert(ElementType X, List L, Position P);
//删除链表
void DeleteList(List L);
//返回链表的头结点
Position Header(List L);
//返回链表第一个数据元素节点
Position First(List L);
//返回当前位置的下一个位置
Position Advance(Position P);
//获取当前位置元素的值
ElementType Retrive(Position P);

        下面是实现基本操作以及简单使用的一个完整的例子。

 

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

struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;
typedef int ElementType;
struct Node 
{
	ElementType Element;
	Position Next;
};

//创建链表
List CreateList();
//遍历链表
void TraverseList(List L);
//清空链表
List MakeEmpty(List L);
//判断给定列表是否为空
int IsEmpty(List L);
//判断节点在给定链表中是否为空
int IsLast(Position P, List L);
//在指定的链表中查找给定元素。
//存在则返回其第一次出现的位置,不存在则返回NULL
Position Find(ElementType X, List L);
//删除链表中的某个元素
void Delete(ElementType X, List L);
//在指定链表中查找给定元素的前驱节点
Position FindPrevious(ElementType X, List L);
//在链表给定位置的后面插入元素
void Insert(ElementType X, List L, Position P);
//删除链表
void DeleteList(List L);
//返回链表的头结点
Position Header(List L);
//返回链表第一个数据元素节点
Position First(List L);
//返回当前位置的下一个位置
Position Advance(Position P);
//获取当前位置元素的值
ElementType Retrive(Position P);

int IsEmpty(List L)
{
	
	return L->Next == NULL;
}

int IsLast(Position P, List L)
{
	return P->Next == NULL;
}

Position Find(ElementType X, List L)
{
	Position P = L->Next;
	while(P != NULL && P->Element != X)
	{
		P = P->Next;
	}
	return P;
}

void Delete(ElementType X, List L)
{
	Position P,TmpCell;
	P = FindPrevious(X,L);	
	if(!IsLast(P,L))
	{
		TmpCell = P->Next;
		P->Next = TmpCell->Next;
		free(TmpCell);
	}
}

Position FindPrevious(ElementType X, List L)
{
	Position P = L;
	while(P->Next != NULL && P->Next->Element != X)
	{
		P = P->Next;
	}
	return P;
}

void Insert(ElementType X, List L, Position P)
{
	Position TmpCell;
	TmpCell = malloc(sizeof(struct Node));
	if(TmpCell == NULL)
	{
		printf("Out of space!\n");
		return;
	}
	TmpCell->Element = X;
	TmpCell->Next = P->Next;
	P->Next = TmpCell;
}

void DeleteList(List L)
{
	Position P,Tmp;
	P = L->Next;
	L->Next = NULL;
	while(P != NULL)
	{
		Tmp = P->Next;
		free(P);
		P = Tmp;
	}
}

Position Header(List L)
{
	return L;
}

Position First(List L)
{
	return L->Next;
}

Position Advance(Position P)
{
	return P->Next;
}

ElementType Retrive(Position P)
{
	return P->Element;
}

List CreateList()
{
	int i;
	Position P,Tmp;
	List L = malloc(sizeof(struct Node));
	P = L;
	for(i = 0; i < 5; i++)
	{
		Tmp = malloc(sizeof(struct Node));
		Tmp->Element = i;
		P->Next = Tmp;
		P = Tmp;		
	}
	P->Next = NULL;
	return L;
}

void TraverseList(List L)
{
	Position P;
	P = L->Next;
	while(P != NULL)
	{
		printf("%d\n",P->Element);	
		P = P->Next;
	}
}

int main(void)
{
	//创建链表
	List L = CreateList();
	//查找元素1在链表中的位置
	Position P = Find(1,L);
	//在元素1后面插入元素8
	Insert(8,L,P);
	//查找元素8前驱结点
	P = FindPrevious(8,L);
	//遍历链表
	TraverseList(L);
	return 0;
}
 

 

2.一元N次多项式相加

        对于两个一元多项式,如果需要对他们进行多项式相加操作,常见的两种思路如下:(1)对于一个多项式,保存其最高项次数HighPowder,以及一个该多项式对应次数分别为0-HighPowder的各项的系数的数组()。(2)多项式中系数不为零的每一项,保存其系数与该项的次数。下面分别用这两种思路实现一元多项式加法操作。

思路一:

数据结构定义:

 

typedef struct Poly
{
	int CoeffArray[11];
	int HighPower;
} *Polynomial;

 实现代码:

 

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

typedef struct Poly
{
	int CoeffArray[11];
	int HighPower;
} *Polynomial;

void ZeroPolynomial(Polynomial Poly)
{
	int i;
	for(i = 0; i < 11; i++)
	{
		Poly->CoeffArray[i] = 0;
	}
	Poly->HighPower = 0;
}

void AddPolynomial(Polynomial Poly1,Polynomial Poly2, Polynomial PolySum)
{
	int i;
	ZeroPolynomial(PolySum);
	PolySum->HighPower = Poly1->HighPower > Poly2->HighPower?
		Poly1->HighPower:Poly2->HighPower;
	for(i = PolySum->HighPower; i >= 0 ; i--)
	{
		PolySum->CoeffArray[i] = Poly1->CoeffArray[i] + Poly2->CoeffArray[i];
	}
}

int main(void)
{
	int i,j,k;
	Polynomial P1,P2,Sum;
	P1 = malloc(sizeof(struct Poly));
	P2 = malloc(sizeof(struct Poly));
	Sum = malloc(sizeof(struct Poly));
	//初始化
	ZeroPolynomial(P1);
	ZeroPolynomial(P2);
	P1->HighPower = 10;
	for(i = 10; i >= 0; i--)
	{
		P1->CoeffArray[i] = i;
	}
	
	P2->HighPower = 8;
	for(j = 8; j >=0; j--)
	{
		P2->CoeffArray[j] = j;
	}
	P2->CoeffArray[8] = 8;
	AddPolynomial(P1,P2,Sum);

	printf("The high power of the Polynomial is %d\n",Sum->HighPower);
	for(k = 0; k <= 10; k++)
	{
		printf("The Coeff of power %d is %d\n",k,Sum->CoeffArray[k]);
	}

	return 0;
}

思路二:

数据结构:

 

typedef struct PolyNode *PtrToNode;

//定义链表节点,也就是多项式中的某一项;
typedef struct PolyNode
{
	int Coeff;
	int Exponent;
	PtrToNode Next;
} PolyNode;

 实现代码:

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

typedef struct PolyNode *PtrToNode;

//定义链表节点,也就是多项式中的某一项;
typedef struct PolyNode
{
	int Coeff;
	int Exponent;
	PtrToNode Next;
} PolyNode;


typedef PtrToNode Polynomial;

/************************************************************
*多项式相加的函数:
*P、Q为存储两个多项式各项的单链表(含头结点)
*Sum为多项式相加结果存放的单链表
*
************************************************************/
void AddPolynomial(Polynomial P,Polynomial Q,Polynomial Sum)
{
	Polynomial PIndex,QIndex,SumIndex;
	PIndex = P->Next;
	QIndex = Q->Next;
	SumIndex = Sum;
	while(!(PIndex == NULL && QIndex == NULL))
	{
		if(PIndex==NULL)
		{
			SumIndex->Next = QIndex;
			QIndex = QIndex->Next;
			SumIndex = SumIndex->Next;
		}
		else if(QIndex == NULL)
		{
			SumIndex->Next = PIndex;
			PIndex = PIndex->Next;
			SumIndex = SumIndex->Next;
		}
		else
		{
			if(PIndex->Exponent > QIndex->Exponent)
			{
				SumIndex->Next = PIndex;
				PIndex = PIndex->Next;
				SumIndex = SumIndex->Next;
				//continue在判断下面if条件时会有异常,类似Java
				//的空引用异常
				continue;
			}
			if(PIndex->Exponent == QIndex->Exponent)
			{
				Polynomial PP = malloc(sizeof(struct PolyNode));
				PP->Exponent = PIndex->Exponent;
				PP->Coeff = PIndex->Coeff + QIndex->Coeff;
				SumIndex->Next = PP;
				PIndex = PIndex->Next;
				QIndex = QIndex->Next;
				SumIndex = SumIndex->Next;
				continue;
			}
			if(PIndex->Exponent < QIndex->Exponent)
			{
				SumIndex->Next = QIndex;
				QIndex = QIndex->Next;
				SumIndex = SumIndex->Next;
				continue;
			}
		}
	}
	SumIndex->Next = NULL;
}

/************************************************************
*遍历单链表(含头结点)函数:
*P:待遍历的链表
*************************************************************/
void TraversePolynomial(Polynomial P)
{
	Polynomial Tmp = P->Next;
	while(Tmp != NULL)
	{
		printf("Coeff is %d and Exponent is %d\n",Tmp->Coeff,Tmp->Exponent);
		Tmp = Tmp->Next;
	}
}



int main(void)
{
	Polynomial Poly1,Poly2,Poly3,Poly11,Poly22;
	int i,j;
	Poly1 = malloc(sizeof(struct PolyNode));
	Poly2 = malloc(sizeof(struct PolyNode));
	Poly3 = malloc(sizeof(struct PolyNode));
	Poly11 = Poly1;
	Poly22 = Poly2;

	//创建两个链表时,需要保证是按照指数递减的方式构造的
	for(i = 5;i >= 1;i--)
	{
		Polynomial Tmp  = malloc(sizeof(struct PolyNode));
		Tmp->Coeff = i;
		Tmp->Exponent = i;
		Poly11->Next = Tmp;
		Poly11 = Poly11->Next;
	}
	Poly11->Next = NULL;
	for(j = 11;j >= 3;j--)
	{
		Polynomial Tmp  = malloc(sizeof(struct PolyNode));
		Tmp->Coeff = j;
		Tmp->Exponent = j;
		Poly22->Next = Tmp;
		Poly22 = Poly22->Next;
	}
	Poly22->Next = NULL;
	TraversePolynomial(Poly1);
	printf("*****************************************\n");
	TraversePolynomial(Poly2);
	AddPolynomial(Poly1,Poly2,Poly3);
	printf("*****************************************\n");
	TraversePolynomial(Poly3);
	return 0;
}
1
1
分享到:
评论

相关推荐

    数据结构_两个链表的合并一元多项式相加

    ### 数据结构:两个链表的合并与一元多项式相加 #### 1. 链表基础概念 链表是一种常见的线性数据结构,它由一系列节点组成,每个节点包含数据元素和一个指向下一个节点的引用(指针)。在本场景中,链表用于表示...

    一元多项式算法c语言的实现

    本主题将深入探讨如何使用C语言的链表数据结构来实现一元多项式的操作。 首先,我们需要理解链表的概念。链表是一种动态数据结构,它的元素(节点)在内存中不是顺序排列的,而是通过指针互相链接。对于一元多项式...

    顺序结构、动态链表结构下的一元多项式的加法、减法、乘法的实现。.docx

    3. 数据处理模块:实现加法、减法和乘法操作,需要考虑多项式相加减时可能出现的零系数项和重复阶项,以及乘法时的合并指数。 4. 主程序模块:控制整个流程,包括用户交互和调用其他模块。 测试数据举例:两个一元...

    数据结构(C)--一元多项式的相加

    本文将深入探讨如何使用C语言来实现一元多项式的相加操作,这是一种基本的数据结构应用。 一元多项式可以看作是形如`a_nx^n + a_{n-1}x^{n-1} + ... + a_1x + a_0`的数学表达式,其中`a_i`是系数,`x`是变量,`n`是...

    数据结构一元多项式相加.rar

    在这个"数据结构一元多项式相加"的项目中,我们主要关注的是如何使用C语言来实现一元多项式的加法运算。一元多项式是数学中的基本概念,由常数、变量及其指数的线性组合构成,例如 ax^n + bx^(n-1) + ... + c,其中a...

    c语言链表实现多项式相加

    在C语言中,链表是一种非常重要的数据结构,它允许我们动态地存储和管理数据。在本场景中,我们将探讨如何使用链表来实现多项式的相加操作。首先,我们需要理解链表的基本概念,然后构建适合多项式表示的链表结构,...

    数据结构 链表 多项式相加 C语言

    数据结构 链表 多项式相加 C语言 struct node { int coef; int expo; struct node *next; }; void input(struct node **head) void display(struct node *head) void add(struct node **head1,struct node *head2...

    c语言 两个一元多项式相加。

    在计算机科学中,一元多项式相加是一个基础的数学操作,它经常被用作算法设计和编程练习的基础。在C语言中实现这个功能,我们可以利用线性表的存储结构来表示多项式,并通过遍历和合并的方式实现相加操作。下面我们...

    数据结构C语言 一元多项式的加减法

    总之,数据结构和C语言的结合使我们能够有效地处理一元多项式加减法的问题,动态链表提供了灵活的数据存储方式,使得算法的实现变得简单且高效。理解和掌握这些知识对于学习更复杂的算法和数据结构有着重要的铺垫...

    一元多项式运算C语言

    为了实现一元多项式相加,首先需要设计一个存储结构来表示多项式。这里采用单链表,并要求链表中的节点按指数递增有序排列。这使得在进行求和时,可以快速比较相邻节点的指数,从而实现合并同类项的操作。在C语言中...

    多项式相加C语言程序.pdf

    "多项式相加C语言程序.pdf" 作为一名IT行业大师,我将为您生成相关的知识点,以下是对标题、描述和标签的详细解释。 多项式相加 多项式相加是指在数学中,对多项式进行加法运算的过程。多项式是一个数学表达式,...

    C语言一元多项式简单计算

    在处理一元多项式的计算时,选择合适的数据结构至关重要。顺序存储(如数组)虽然简单直观,但在实际应用中存在一定的局限性。对于一元多项式来说,其项数不确定,特别是当多项式的系数较大时,采用顺序存储可能会...

    一元多项式相加c实现

    ### 一元多项式相加C语言实现 #### 概述 本文将详细介绍如何使用C语言来实现一元多项式的相加操作,并采用两种不同的数据结构:数组和链表来进行实现。通过这两种方法,我们可以更好地理解一元多项式在计算机中的...

    一元多项式相加实验报告(C语言实现)

    ### 一元多项式相加实验报告(C语言实现) #### 问题描述 在一元多项式的加法运算中,我们面临的问题是如何有效地实现两个一元多项式的加法运算。具体而言,给定两个一元多项式 \(A(x)\) 和 \(B(x)\),我们的目标...

    一元多项式相加实验报告

    这个实验报告展示了如何使用链表数据结构和基本的C语言编程技术来实现一元多项式的操作,这对于理解数据结构和算法在实际问题中的应用是非常有帮助的。通过这种方式,可以方便地处理和计算复杂的数学表达式,为...

    C语言:一元多项式的表示及其运算(含注释)

    在IT领域,特别是编程,理解和操作一元多项式是数据结构和算法中的基本概念。本文将深入探讨如何在C语言中表示一元多项式以及如何进行相关运算,如相加。C语言是一种强大的、低级别的编程语言,适用于实现高效且灵活...

    一元多项式的相乘(C链表实现).

    在这个实现中,我们使用C语言来实现一元多项式的相乘,包括多项式的创建、相加和相乘的实现。 多项式的创建是指根据输入的系数和指数来建立一个链表,每个结点包含系数、指数和指针三个部分。我们可以使用结构体来...

    数据结构课程设计—用链表实现一元多项式计算器

    本课程设计旨在设计一个使用链表实现的一元多项式计算器,以掌握数据结构的应用、算法的编写、C语言的编程和 程序调试的基本方法。通过本课程设计,学生将熟悉掌握一元多项式在链式存储结构上的实现,能够按照指数...

    一元稀疏多项式计算器

    通过上述分析可以看出,实现一元稀疏多项式计算器涉及到了多个方面的知识,包括数据结构的设计、链表的使用、面向对象的设计方法以及多项式的基本运算原理。这些知识点的综合应用能够帮助我们构建一个高效且功能完备...

    数据结构一元多项式的加法运算

    在编程中,我们通常使用数据结构来表示这种数学对象,并实现它们的基本操作,如加法。 链表是一种常用的数据结构,它由一系列节点组成,每个节点包含数据元素和指向下一个节点的指针。在实现一元多项式时,我们可以...

Global site tag (gtag.js) - Google Analytics