数据结构前四章复习
第一章绪论
数据结构是什么
数据结构是一门研究非数值计算的程序设计问题中 计算机对的操作对象 以及 它们之间的关系 和 操作 等的学科。(背下来)
第二章线性表
概念
一个线性表是n个元素的有限序列。
逻辑特性
- 存在唯一一个被称为第一个的元素,和唯一一个被称为最后一个的元素。
- 除了第一个元素之外,集合中每一个元素均只有一个前驱;除了最后一个元素之外,集合中每一个元素均只有一个后继。
存储结构以及核心操作
- 线性表的顺序表示:用一组地址连续的存储单元依次存储线性表的数据元素。
动态分配顺序的存储结构
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef strict{
ELemtype *elem;//表示线性表的基地址,在未开辟内存空间时,可以存储的数据个数为0
int length;//线性表当前长度
int listsize;//当前分配的存储容量
}SqList;
- 动态分配内存的初始化
Status Init List_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;
}//InitList_Sq
- 在第i个元素之前插入一个元素
Status ListInsert_Sq(SqList &L,int i,ElemType e){
//确定i值的合法化,i小于L.listsize,大于等于1
//由于存储空间增加,先考虑空间是否足够
if(i<1||i>L.listsize){
newbase= (ElenType *)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if(!newbase) exit(OVERFLOW);
//只有L.elem被赋值此时的线性表才能发挥存储元素的作用
L.elem=newbase;
//如果长度不够,改变长度此时现有长度值
L.listsize+=LISTINCREMENT;
}
//将增加的位置之后的元素后移
q = &(L.elem[i-1];
for(p= &(L.elem[L.lenth-1];p>=q;—-p){
*(p+1)=*(p);
*q=e;
//添加后长度加一
L.lenth++;
}
}
- 线性表的删除操作,删除第i个操作
Status ListDelete_s(Sq_List L,int i,ElemType e){
//判断数据是否合理
if(i<1||i>L.listsize) exite(OVERFLOW);
q = &L.elem[i-1];
//保留这个位置的元素的值
e = *q;
//将删除的位置的元素的后面的元素前移
for(p=q;p<L.Elem[L.listsize-1];p++) *(p)=*(p+1);
//改变元素lenth值
--L.lenth;
return OK;
}
- 线性表的查找操作,按值查找等于e的元素
int LocateElem_sq(Sq_List L,ElemType e){
for(int i=1;i <= L.lenth;i++){
if(L.elem[i-1]==e)
return i;//i为该元素的位序,而不是下标
}
return 0;
}
课本上的代码:
emmm,我没看懂,明天问问
- 顺序表的合并
分析:将非递减的线性表La和Lb合并到Lc中,相同元素一样合并,不删除。
void MergeList_Sq(SqList La,SqList Lb,SqList Lc){
Lc.listsize=Lc.lenth=La.listsize+Lb.listsize;
Lc.elem = (ElemType *)malloc((La.listsize+Lb.listsize)*sizeof(ElemType));
pa=La.elem; pb=Lb.elem;
pa_last=La.elem+La.lenth-1; pb_last=Lb.elem+Lb.lenth-1;
//La和Lb第一和最后一个元素的地址
while(pa<=pa_last &&pb<=pb_last){
if(*(pa)<=*(pb)){
*(pc)=*(pa);
pa++;pc++;}
else
*pc ++ = *pb++;
}
//结尾处理
while(pa<=pa_last){
*pc++=*pa++;}
while(pb<=pb_last){
*pc++=*pb++;}
return 0;
}
总结:
1.为pc开辟相应的内存空间,同时记得改变L.lenth的值。
2.用双指针的方式,pa和pb同时在两条链表上移动,进项选择,注意题意中的非递减序列,和递增序列的含义不相同。
线性表的链式表示和实现(称作线性链表或单链表)
链式存储结构的特点是用一组任意的存储单元存储线性表(这组单元可以是连续的,也可以是不连续的)
//只含有一个指针域的单链表
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*linkList;
- 获取链表的第i个元素
Status GetElem(LinkList L,int i,ElemType *e){
p = L->next;//越过首元结点
k = 1;
while( k<i && p){
k++;
p=p->next;
}
if(!p) return ERROR;
*e = p->data;
return OK;
}
- 将两个有序链表合并成一个有序链表
Status MergeList_L(LinkList La,linkList Lb,LinkList Lc){
pa = La->next; pb = Lb -> next;
Lc = pc = La;
while(pa && pb){
if(pa->data <= pb->data){
pc->next=pa; pc = pa; pa = pa -> next;
}
else{
pc->next = pb; pc=pb; pb=pb->next;
}
pc->next=pa?pa:pb;
free(Lb);
}
}
线性表的静态单链表存储结构——静态链表
- 静态链表存储结构
#define MAXSIZE 1000
typedef struct {
ElemType data;
int cur;
} component,SLinkList[MAXSIZE];
循环链表
经典应用
- 一元多项式的表示及相加