数据结构期末笔试复习,内容是上课课件和课本上的部分
一、线性表
线性表是n(n≥0)个数据元素(也称结点或元素) 组成的有限序列 k0, k1,…, kn-1
常用的运算:1)表的初始化 2)判表是否为空 3)判表是否满 4)求表长 5)取出 6)查找 7)插入 8)删除
• 线性表的类描述
template<class T>
class LinearList
{
private:
T * data;
int MaxSize;
int Last;
public:
LinearList(int MaxSize=defaultSize);
~LinearList(void);
boolean ListEmpty(void);
boolean ListFull(void);
int ListLength(void) const;
T GetElem(int i);
int LocateElem(T& x) const;
int InsertElem(T& x,int i);
int DeleteElem(int i);
}
// 构造函数
template<class T>
LinearList<T>::LinearList(int sz)
{
if(sz>0)
{
MaxSize=sz;
Last=0;
data=new T [MaxSize];
}
}
//返回线性表中第i个结点的值
template<class T>
T LinearList<T>::GetElem(int i)
{
\\ 如果i不在表的索引范围则返回NULL,否则返回data[i]
return(i<0||i>=Last)?NULL:data[i];
}
// 在线性表中第i个位置插入值为x的结点
template<class T>
boolean LinearList<T>::InsertElem(T& x, int i)
{
if(i<0||i>Last||Last==MaxSize) // 无法插入
return FALSE;
else
for(int j=Last;j>i;j--) data[j]=data[j-1];
// 当前等于当前前一个,i后面的全都后移一位
data[i]=x;
Last++;
}
算法 2.9 删除线性表中第i个结点
template<class T>
boolean LinearList<T>:: DeleteElem( int i)
{
if(i<0||i>=Last||Last==0)
return FALSE;
else
for(int j=i;j<Last-1;j++) data[j]=data[j+1];
// Last是下一个插入位置的索引,Last-1是最后一个数的索引
// i后的每一个都要往前移
Last--;
return TRUE;
}
二、数组
数组(向量)是由同一种数据类型的数据元素组成的线性表
数组是顺序存储的.
它是一种随机存储结构
// 算法 2.12 在向量第i个位置插入值为x的新结点
template<class T>
boolean Vector<T>:: Insert(T& x, int i)
{
if(Vectorlength==ArraySize)
{
cerr<<“Overflow”<<endl; return FALSE;
}
else
if(i<0||i>VectorLength)
{
cerr<<“position error”<<endl;
return FALSE;
}
else
{
for(int j=VectorLength-1;j>=i;j--)
elements[j+1]=elements[j];
// 和数组一样,i后面都往后移,这个是后一个等于当前,数组是当前等于前一个
elements[i]=x; // 直接插入就行
Vectorlength++;
return TRUE;
}
}
删除也是和数组差不多的,模仿上面就行,不在贴代码了
向量的应用
并运算
就是合并两个数组,数组相同元素只留下一个
// 算法2.14 将两个向量合并成一个向量
template<class T>
void Union(Vector<T>& Va, Vector<T>& Vb)
{
int n=Va.GetLength();
int m=Vb.GetLength();
for(int i=0;i<m;i++)
{
T x=Vb.Getnode(i); // 遍历到集合B中元素x
int k=Va.Find(x); // 返回集合A的x的索引
if(k==-1) // 如果A中没有找到x(k==-1),则在A中加入x
{
Va.Insert(x,n);
n++;
}
}
}
时间分析
查找需要比较,插入需要移动
最好情况是a、b相等
最坏情况是a、b不相等,使a长度增加
交运算
// 算法2.15 两个向量之间的“交”运算
template<class T>
void Intersection(Vector<T>& Va,Vector<T>& Vb)
{
int n=Va.GetLength();
int m=Vb.GetLength();
int i=0;
while(i<m)
{
T x=Vb.Getnode(i);
int k=Va.Find(x);
if(k==-1) // 如果另一个集合中找不到,则删掉当前元素
{
Vb.Remove(i);
m--; // 元素减少,i不变,因为删掉了i位置的元素,下一次遍历还是i这个位置
}
else i++; // 找到了就i++,遍历下一个位置的元素
}
}
时间分析
Josephus问题求解
// 算法2.16 模拟Josephus问题求解
void Josephus(Vector<int>& P, int n, int s, int m)
{
int k=1;
for(int i=0;i<n;i++) // 初始化,把人给放进去
{
P.Insert(k,i);
k++;
}
int s1=s; // 报数开始位置
for(int j=n;j>=1;j--)
{
s1=(s1+m-1)%j; // 自己也要报数,要-1,因为是一个圈,%j
if(s1==0)
s1=j;
int w=P.Getnode(s1-1); // s1-1是索引,s1是第几个人
P.Remove(s1-1);
P.Insert(w,n-1);
}
}
三、栈
栈是一种操作受限的线性表,规定栈中数据元素的插入和删除只能在表的一端进行,这一端称 为栈顶,另一断称为栈底.又称为后进先出表.
中缀表达式
运算符何时进栈、何时出栈
当前 ) 就要出栈,如果栈顶是*或/就要除非当前是( ,否则都出栈
重在理解吧,不要死记硬背,模拟几次就会了
后缀表达式
后缀表达式只需要一个栈
中缀转后缀
只要运算符栈,,遇到数字直接写在表达式中,遇到)直接出栈,栈中+、-不能在*、/上边,需要先出*、/再让+、-入栈、
还是理解吧,其实好简单,不懂就看书!
四、队列
队列也是一种操作受限的线性表, 规定插入在表 的一端(队尾rear),删除在队的另一端(队头front), 又称为先进先出表(FIFO)
建立顺序队列必须为其申请一片连续的存储空间,并设置队头 指针front和队尾指针rear,队头指针指向队头元素,队尾指针指向下一个入队元素的存储位置。
每插入一个元素, rear 增 1,每删除一 个元素front增1。当 front=rear时,为空队列
当rear增加到指向所分配空间之外时,队列无法再插入元素 ,但这时往往还有大量空间未被占用
所以要用到循环队列
总结
这样复习太累了