您的位置:首页 > 理论基础 > 数据结构算法

重学数据结构001――链表基本操作与一元多项式相加

2011-11-13 00:10 495 查看
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;
}


本文出自 “wawlian说” 博客,请务必保留此出处http://wawlian.blog.51cto.com/242845/712862
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: