多项式的线性表可以用数组实现,也可以用链表实现。用数组实现有两种方法,一种是顺序存储结构直接表示,另一顺序存储结构表示非零项。用链表实现链表中的每个结点存储多项式中的一个非零项,包括系数个指数两个数据域以及一个指针域。
线性表的抽象数据类型描述
类型名称:线性表(List)
数据对象集:线性表是
个元素构成的有序序列
操作集:线性表
,整数
表示位置,元素
线性表基本操作主要有(数组实现):
- 初始化一个线性表(建立空的顺序表);
#include <stdio.h> #include <stdlib.h> typedef struct LNode *List; typedef int ElementType; #define MAXSIZE 100 //宏定义MAXSIZE struct LNode{ ElementType Data[MAXSIZE]; int Last; }; struct LNode L; List PtrL; List MakeEmpty() { List PtrL; PtrL = (List)malloc(sizeof(struct LNode)); //malloc需要添加头文件stdlib.h PtrL->Last = -1; //代表最后一个元素 return PtrL; }
- 根据位序K,返回相应元素;
- 在线性表中查找X的第一次出现位置;
int Find(ElementType X, List Ptrl) { int i = 0; while (i <= PtrL->Last&&PtrL->Data[i] != X) i++; if (i > PtrL->Last) return -1; else return i; }
- 在位序i前插入一个新元素X;
void Insert(ElementType X, int i, List PtrL) { int j; if (PtrL->Last == MAXSIZE - 1){ //表已满,不能插入 printf("表满"); return; } if (i<1 || i>PtrL->Last + 2){ printf("位置不合法"); return; } for (j = PtrL->Last; j >= i - 1; j--) PtrL->Data[j + 1] = PtrL->Data[j]; //将第i个数之后的数字进行向后移动 PtrL->Data[i - 1] = X; //在位置i的前一项插入新元素 PtrL->Last++; //Last指向最后一个元素 return; }
- 删除线性表位置i的元素
void Delete(int i, List PtrL) { int j; if (i<1 || i>PtrL->Last + 1){ printf("不存在第%d个元素", i); return; } for (j = i; j < PtrL->Last; j++) PtrL->Data[j - 1] = PtrL->Data[j]; //将第i之后的元素往前移动 PtrL->Last--; return; }
- 线性表的长度。
线性表基本操作主要有(链式存储实现):
- 求线性表的长度
#include <stdio.h> #include <stdlib.h> typedef struct LNode *List; typedef int ElementType; struct LNode{ ElementType Data; List Next; }; struct LNode L; List PtrL; int length(List PtrL) { List p = PtrL; //p指向的第一个结点 int j = 0; while (p) { p = p->Next; j++; } return j; }
- 查找线性表中的元素
List FindKth(int K, List PtrL) //按序号查找 { List p = PtrL; int i = 1; while (p != NULL&&i < K) { p = p->Next; //表没有找到最后和还没找到第K个元素 i++; } if (i == K) return p; //找到第K个,返回指针 else return NULL; //否则返回空 } List Find(ElementType X, List PtrL) //按值查找 { List p = PtrL; while (p != NULL&&p->Data != X) p = p->Next; return p; }
- 在线性表中插入元素
List Insert(ElementType X, int i, List PtrL) { List p, s; //原始链表和加入结点初始化 if (i == 1){ //插入在表头 s = (List)malloc(sizeof(struct LNode)); s->Data = X; s->Next = PtrL; return s; } p = FindKth(i - 1, PtrL); if (p = NULL){ printf("参数i错误"); return NULL; } else{ s = (List)malloc(sizeof(struct LNode)); s->Data = X; s->Next = p->Next; //新结点插入在第i-1个结点的后面 p->Next = s; return PtrL; } }
- 在线性表中删除元素
List Delete(int i, List PtrL) { List p, s; //原始链表和加入结点初始化 if (i == 1){ //删除表头 s = PtrL; if (PtrL != NULL) PtrL = PtrL->Next; else return NULL; free(s); //释放被删除结点 return PtrL; } p = FindKth(i - 1, PtrL); if (p == NULL) { printf("第%d个结点不存在", i - 1); return NULL; } else if (p->Next == NULL) { printf("第%d个结点不存在", i); return NULL; } else { s = p->Next; p->Next = s->Next; free(s); return PtrL; //释放被删除结点 } }
广义表 :
- 广义表是线性表的推广
- 对于线性表而言,n个元素都是基本的单元素
- 广义表中,这些元素不仅可以是单元素也可以是另一个广义表。
例:给定二元多项式:
,
可以将此式子写成关于x的一元多项式:
用链表表示为:
广义表的定义:
typedef struct GNode *GList; struct GNode { int Tag; //标志域:0表示结点是单元素,1表示结点是广义表 union{ //不同类型的数据公用存储空间 ElementType Data; GList SubList; }URegion; GList Next; //指向后继结点 };
多重链表:
定义:链表中的节点可能同时隶属于多个链
注意:多重链表中的结点的指针域会有多个如上例。
包含两个指针域的链表并不一定是多重链表,比如在双向链表不是多重链表。
用途:对于图和树等相对复杂的数据结构都可以采用多重链表方式实现存储。
对于一个数组,多重链表的每个结点通过两个指针域(行和列)以及数值构成。