基本概念和术语:
数据:是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机并被计算机程序处理的符号总称。
数据元素: (有时也称为结点,顶点,记录)是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
数据对象:是性质相同的数据元素的集合,是数据的一个子集
数据结构及其形式化描述
数据结构:是带有结构的数据元素的集合。||是相互之间存在一种或多种特定关系的数据元素的集合。
数据类型
1、数据类型:是一个值的集合和定义在该值上的一组操作的总称。
抽象数据类型:是指一个数据结构以及定义在该结构上的一组操作。
由用户定义,用以表示应用问题的数据模型。它与数据类型实质上是一个概念,但其特征是使用与实现分离,实行封装和信息隐蔽。
算法的特征和要求,掌握算法的时间复杂度和空间复杂度
算法是对特定问题求解步骤的一种描述,它是指令的有限序列。
有五个重要的特性:有穷性,确定性,可行性,输入,输出。
时间复杂度:算法中基本操作重复的次数。
线性表
线性结构特点:若结构是非空有限集,则有且仅有一个开始结点和一个终端结点,除首尾结点外,其他结点只有一个直接前驱和一个直接后继。
基本操作:
初始化:InitList(&L)
删除表:DestroyList(&L)
表置空:ClesrList(&L)
表判空:ListEmpty(L)
表长度:ListLength(L)
取元素:GetElem(L,i,&e)
定位:LocateElem(L,e,compare())
求前驱:PriorElem()
求后继:NextElem()
前插操作:ListInsert()
删除操作:ListDelete()
顺序表的随机存取;
线性表的顺序存储结构是一种随机存取的存储结构。
- 顺序表为空、为满的判定(见2.算法);
- 顺序表的插入和删除操作(算法);
插入:
Status Insert_Sq (Sqlist &L,int i ,ElemType e) { int j ; ElemType *p,*q; ElemType * newbase; if ( i<1 || i >L.length+1) return ERROR ; if (L.length>=L.listsize)//判断表是否已满 { newbase = (ElemType * )realloc (L.elem, ( L.listsize + LISTINCREMENT) * sizeof(ElemType)); if (!newbase) exit (OVERFLOW); L.elem = newbase; L.listsize += LISTINCREMENT; } q = &(L.elem[i-1]); //q为插入位置 for (p =& (L.elem[L.length-1]);p >= q; --p) *(p+1)= *p; //插入位置及之后元素右移 *q = e; ++L.length; return OK;}
删除:
Status ListDelete_Sq(SqList &L, int i, ElemType &e){ //在顺序表L中删除第i个元素,并用e返回其值 ElemType *p; ElemType *q; if ( i < 1 || i > L.length ) return ERROR ; //i值不合法 p = &(L.elem[i-1]); //p为被删除元素的位置 e = *p; //被删除元素的值赋给e q =L.elem+L.length-1; //表尾元素的位置 for ( ++p; p <= q; ++p) *(p - 1) = *p; //被删除元素之后的元素左移 --L.length; return OK;}
2、掌握有关线性表链式存储的内容:
(1)单链表为空的判定(带头结点、不带头结点);
(2)单链表的查找(算法);时间复杂度T(n) = O(n)。
Status GetElem_L(LinkList L,int i,ElemType &e){ LinkList p; int j; p=L->next; j=1; //初始化,p指向首元结点,计数器j初值为1 while(p&&j<i){ //顺链表向后扫描,直到p为空或p指向第i个元素 p=p->next; //p指向下一个结点 ++j; //计数器j相应加1 } if(!p || j>i) return ERROR; //i值不合法i>n或i<=0 e=p->data; //取第i个结点的数据域 return OK; }
(3)单链表的插入、删除操作(算法)。
插入:-----
//在带头结点的单链表L中第i个位置插入值为e的新结点 Status ListInsert_L(LinkList &L,int i,ElemType e){ LinkList p,s; int j; p=L; j=0; while(p&& (j<i-1)){ p=p->next; ++j;//查找第i-1个结点,p指向该结点} if(!p ||j>i-1) return ERROR; s=(LinkList)malloc(sizeof(LNode));//生成一个新的结点*s s->data=e;//将结点*s的数据域设置为e s->next=p->next;//将结点*s的指针域指向结点b p->next=s;//将结点*p的指针域指向结点*s return OK; }
删除:
//在带头结点的单链表L中,删除第i个元素,并由e返回其值 Status ListDelete_L(LinkList &L,int i,ElemType e){ LinkList p,q; int j; p=L; j=0; while((p->next)&&(j<i-1))//查找第i-1个结点,p指向该结点 { p=p->next; ++j; } if(!(p->next) || (j>i-1)) return ERROR;//当i>n或i<1时,删除位置不合理 q=p->next;//临时保存被删除结点的地址以备释放 p->next=q->next;//改变删除结点前驱结点的指针域 e=q->data; free(q);//释放删除结点的空间 return OK; }
栈和队列
1、顺序栈的表示,栈操作的特点以及为空、为满的判定;
base 表示栈底指针,用 top 指示栈顶指针
判空:S.top == S.base
栈满:S.top-S.base = S. stacksize
2、栈的入栈和出栈操作(算法);后进先出,先进后出
入栈:
Status Push(SqStack &S,SElemType e){ //插入元素e为新的栈顶元素 if(S.top-S.base>=S.stacksize)//栈满 {S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType)); if (!S.base) exit (OVERFLOW);//存储分配失败 S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; } *S.top++=e; return OK;}
出栈:
Status Pop(SqStack &S,int &e){ //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR if(S.top==S.base)return ERROR; e=*--S.top; return OK; }
3、队列的表示以及循环队列为空、为满判定;
◆方法一 :用一个计数器来记载队列中的元素个数。
• 初始化队列时c = 0;
• 当入队时,计数变量+1( c = c+1 )
• 当出队时,计数变量-1 (c = c-1)
• 当计数变量 = maxsize时,队满
• 当计数变量 = 0时,队空
◆ 方法二:设一个标志位用来区别队列是空还是满。
• 初始化队列时:Q.front = Q.rear,标志位为 false(0)
• 入队置标志位为true(1)
• 出队置标志位为false(0)