目录
一、顺序表示的实现
#define LIST_INIT_SIZE 80
#define LISTINCREMENT 10
typedef struct data{
char name[8];
int age;
char sex[2];
float score;
}Elemtype;
typedef struct{
ElemType *elem;
int length;
int listsize;
}SqList;
二、顺序表的基本操作
1.初始化
Status InitList_Sq(SqList *L){
L->elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L->elem) exit(OVERFLOW);
L->length=0;
L->listsize=LIST_INIT_SIZE;
return OK;
}
2.销毁线性表
Status DestroyList(SqList *L){
free(L->elem);
return OK;
}
3.判断线性表是否为空
Status ListEmpty(SqList L){
if(L.length==0) return TRUE;
else return FALSE;
}
4.求L的长度
5.求前驱的值
6.插入操作算法
(1)数组下标控制
(2)指针控制
if(i<1||i>L.length+1) return ERROR;
if(L.length>=L.listsize){//当前存储空间已满,增加分配
newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCRELMENT)*sizeof(ElemType));
if(!newbase) exit(OVERFLOW);
L.elem=newbase;//新基址
L.listsize+=LISTINCREMENT;}
插入算法时间复杂性分析 n/2
即O(n)
7.删除算法
(1)指针控制
Status ListDelete_Sq(SqList *L,int i,ElemType *e){
if((i<1)||(i>L->length)) return error;
ElemType *p;
p=&(L->elem[i-1]);
e=p;
ElemType *q;
q=L->elem+L->length-1;
for(++p;p<=q;++p) *(p-1)=*p;
--L->length;
return OK;
}
(2)数组下标控制 同理
删除操作时间复杂性分析(n-1)/2
即O(n)
8.顺序表的优缺点
三、线性表的链式表的表示和实现
1.单链表
*头结点:使对第一个元素的操作与对其他元素的操作保持一致
具体基本操作的实现由于大一上已经基本掌握,不再赘述
- 查找结点、插入结点、删除结点、将单链表重新置为空表算法的时间复杂度均为
- 设移动指针为p,插入算法(在i之前)时,while(p&&j<i-1);删除算法时,p的后继代表要删除的元素,因此p->next不能为空
- 优缺点:
2.循环链表
即单链表的最后一个结点的指针域指向头指针
- 多采用尾指针(查找第一个和最后一个结点都容易)
- 注意区分头指针和头结点、尾指针和尾结点(在拼接两个链表时,如果没有尾结点的话改变最后一个结点的指向就需要遍历拼接时在前面的整条链表,所以时间复杂度就是这条链表的长度;若最后要成为一个整体的循环链表,后面的链表的最后一个结点的指针域也要改变,时间复杂度相应增加)
3.双向链表
(1)优缺点:![](https://i-blog.csdnimg.cn/blog_migrate/084f792081f236b1dd59a74b3f308df3.png)
(2)c语言实现
typedef struct DulNode{
ElemType data;
struct DulNode *prior;
struct DulNode *next;
}DulNode,*DuLinkList;
(3)插入操作:在a节点前插入一个节点s,其值为e
思路:先把s的前后结点建立好,再分别改变a的前驱和a的原前驱的后驱
(4)删除操作:删除a节点
思路:先把a节点后继节点和a节点前驱连接,再free(p)
四、一元多项式的表示
稀疏多项式的顺序表存储浪费空间->用链式存储
c语言实现:
typedef struct{
float coef;//系数
int expn;//指数
}term,ElemType;
typedef LinkList polynomial;
对线性表进行二分查找时,要求线性表必须以顺序方式存储,且数据元素有序