数据结构入门第二课
目录
- 数据结构入门第二课
- 引子 多项式的表示
- 方法1 顺序结构表示多项式各项
- 方法2 顺序结构表示非零项
- 方法3 链表结构存储非零项
- 多项式问题的启示
- 线性表
- 线性表的抽象数据类型描述
- 线性表的顺序存储实现
- 主要操作的实现
- 初始化(建立空的顺序表)
- 查找
- 插入(第i个位置)
- 删除(第i个位置)
- 主要操作的实现
- 线性表的链式存储实现
- 主要操作的实现
- 求表长
- 查找
- 按序号查找(FindKth)
- 按值查找
- 插入
- 删除
- 主要操作的实现
- 广义表
- 多重链表
- 引子 多项式的表示
引子 多项式的表示
方法1 顺序结构表示多项式各项
数组各分量对应多项式各项
问题:可能造成空间浪费
方法2 顺序结构表示非零项
将一个多项式看成系数和指数的二元组合,用结构数组表示:数组分量是由指数系数组成的结构,对应一个非零项。
要点:按指数大小有序存储
方法3 链表结构存储非零项
链表中每个结点存储多项式中的一个非零项,包括系数和指数两个数据域以及一个指针域。
typeof struct PolyNode* Polynomial;
struct PolyNode{
int coef;
int expon;
Polynomial link;
}
多项式问题的启示
同一个问题可以有不同的表示(存储)方法;
有一类共性问题:有序线性序列的组织和管理;
线性表
线性表:由同类型数据元素构成有序序列的线性结构
表中元素个数称为线性表的长度;
线性表中没有元素时,称为空表;
表起始位置称为表头,表结束位置称为表尾;
线性表的抽象数据类型描述

线性表的顺序存储实现
利用数组的连续存储空间顺序存放线性表的各元素

主要操作的实现
-
初始化(建立空的顺序表)
/* 初始化 */ List MakeEmpty() { List L; PtrL = (List)malloc(sizeof(struct LNode)); L->Last = -1; return PtrL; }
-
查找
/* 查找 */ #define ERROR -1 Position Find( List L, ElementType X ) { int i = 0; while( i <= L->Last && L->Data[i]!= X ) i++; if ( i > L->Last ) return ERROR; /* 如果没找到,返回错误信息 */ else return i; /* 找到后返回的是存储位置 */ }
-
插入(第i个位置)
/* 插入 */ bool Insert( List L, ElementType X, int P ) { /* 在L的指定位置P前插入一个新元素X */ int i; if ( L->Last == MAXSIZE-1) { /* 表空间已满,不能插入 */ printf("表满"); return false; } if ( P<0 || P>L->Last+1 ) { /* 检查插入位置的合法性 */ printf("位置不合法"); return false; } for( i=L->Last; i>=P; i-- ) L->Data[i+1] = L->Data[i]; /* 将位置P及以后的元素顺序向后移动 */ L->Data[P] = X; /* 新元素插入 */ L->Last++; /* Last仍指向最后元素 */ return true; }
-
删除(第i个位置)
/* 删除 */ bool Delete( List L, int P ) { /* 从L中删除指定位置P的元素 */ int i; if( P<0 || P>L->Last ) { /* 检查空表及删除位置的合法性 */ printf("位置%d不存在元素", P ); return false; } for( i=P+1; i<=L->Last; i++ ) L->Data[i-1] = L->Data[i]; /* 将位置P+1及以后的元素顺序向前移动 */ L->Last--; /* Last仍指向最后元素 */ return true; }
线性表的链式存储实现
不要求逻辑上相邻的两个元素物理上也相邻;通过链建立起数据元素之间的逻辑关系。
插入输出不需要移动数据元素,只需要修改链。
typedef struct LNode *PtrToLNode;
struct LNode {
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;
typedef PtrToLNode List;
主要操作的实现
-
求表长
int length(List PtrL){
List p=PtrL;//指向表的第一个结点
int j=0;
while(p){
p=p->Next;
j++;
}
return j;
}
-
查找
-
按序号查找(FindKth)
List FindKth(List L, int K) { List p = PtrL; /* p指向L的第1个结点 */ while ( p!=Null && i
Next; i++; } if(i==K)return P; else return NULL; } -
按值查找
Position Find( List L, ElementType X ) { Position p = L; /* p指向L的第1个结点 */ while ( p && p->Data!=X ) p = p->Next; /* 下列语句可以用 return p; 替换 */ if ( p ) return p; else return ERROR; }
-
-
插入
/* 带头结点的插入 */
bool Insert( List L, ElementType X, Position P )
{ /* 这里默认L有头结点 */
Position tmp, pre;
/* 查找P的前一个结点(可用p=Find(Ptrl,x);代替 */
for ( pre=L; pre&&pre->Next!=P; pre=pre->Next ) ;
if ( pre==NULL ) { /* P所指的结点不在L中 */
printf("插入位置参数错误\n");
return false;
}
else { /* 找到了P的前一个结点pre */
/* 在P前插入新结点 */
tmp = (Position)malloc(sizeof(struct LNode)); /* 申请、填装结点 */
tmp->Data = X;
tmp->Next = P;
pre->Next = tmp;
return true;
}
}
-
删除

/* 不带头结点的删除,第i位置*/
List Delete( List L, int i )
{ /* 这里默认L有头结点 */
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);/*查找i-1个结点*/
if(p==NULL){
printf("the %d node is not exist",i-1);
return NULL;
}else if(p->Next==NULL){
printf("the %d node is not exist",i-1);
return NULL;
}else{
s=p->Next;
p->Next=s->Next;
free(s);
return PtrL;
}
}
广义表


多重链表



