《数据结构打卡》第1天
昨天一些情况的原因,断发了一天的学习总结打卡,实在抱歉,今晚发的是今天的。
还有一个就是,总感觉一学习,脑子就不够用似的,就像消了磁的硬盘一样,总是学一点忘一点,以前学过的好多都忘了,现在再来复习一遍。
1、简述栈和队列两种数据类型的相同点和差异点(5分)
相同点:
(1).栈和队列都是线性表;
(2)栈和队列的插入都限定在表尾进行;
(3)栈和队列的插入和删除的时间复杂度都是O(1)。
不同点:
(1).栈是先进后出(FILO)的线性表,队列是先进先出(FIFO)的线性表;
(2)栈的删除在栈顶,队列的删除在队尾;
(3)顺序栈支持多栈共享,顺序队不支持。
2、试编写队列初始化、入队、出队的算法(5分)
队列的初始化:
Status InitQueue(SqQueue &L){
Q.front = Q.rear = 0;
return ok;
}
队列的入队操作:
Status EnQueue(SqQueue L,QElemType &e){
if((Q.rear + 1) % MaxQsize == Q.front) return error; //判断是否队满
Q.base[rear] = e; //元素e从队尾rear开始入队
Q.rear = (Q.rear+1) % MaxQsize //尾指针向后移动1位
}
队列的出队操作:
Status DeQueue(SqQueue &L,QElemType &e){
if(Q.front == Q.rear) return error; //判断是否队空
e = Q.base[front]; //元素e从队头front开始出队
Q.front = (Q.front + 1) % MaxQsize //队头指针向后移1位
return ok;
}
3、试编写链表的算法,要求实现头插入、头删除(5分)
单链表的头插入法:
void CreateList_H(LinkList &L int n){
Lnode *p; //声明一个p指针
L = new Node; L->next = Null; //生成头结点L,L的指针域置空
for(i=n;i>0;--i){ //从第n~1个结点开始插入,每次插入的结点大于0,则结点数就-1
p = new Node; //p指向新结点
cin >> p->data; //输入值
p->next = L->next; //首先把L的^空域赋给p的指针域
L->next = p; //L指向新插入的结点p
}
return ok;
}
单链表的头删除法:
//还没有解决
单链表的尾插入法:
//还没有解决
4、请编写单链表的初始化,单链表的插入,删除算法(5分)
(1)单链表的初始化:
Status InisList(LinkList &L){
L = new Node; //或 L = (Lnode)malloc(sizeof(Lnode));
L->next = Null;
}
(2)单链表的求长度ListLength(L,i){
int ListLength(LinkList &L,int i){
LNode *p; p=L;
while(p){ //或者写成while(p!=Null)
i++; //那么i计数加1
p=p->next; //p继续指向下一结点
}
return i; //返回单链表中结点个数
}
}
()单链表的插入(在第i个元素之前插入元素e):
首先找到第i-1个结点的位置
生成新结点s,赋值给s
插入新结点
Status InsertList(LinkList L int i ElemType &e){
LNode *p;
p = L; int j = 0; //p结点从头结点开始找,声明计数器j作为计数
while(p && j<i-1){ //若p不为空,且要查找的位置小于i-1
p = p->next; //则p继续寻找下一结点
++j; //计数器加1
}
if(!p || j>i-1) return error; //若p为空,或者找不到第i-1个结点位置,则报错
s = new Node; s->data = e; //生成新结点s,数据域赋值e
s->next = p->next; //新结点s指向第i个结点
p->next = s; //第i-1个结点指向s结点
return ok; //完成插入
}
()单链表的删除(在表中删除第i个结点)
首先找到第i-1个结点的位置,用p指向
再用q指针指向第i个结点的位置
最后删除第i个结点
Status DeleteList(LinkList L int i ElemType &e){
LNode *p,*q //p指针用来寻找下一结点,q指针用来删除第i个结点
p = L; int j = 0;
while(p->next || j<i-1){
p = p->next; //p指针加1
++j;
}
if(!(p->next) || j>i-1) return error; //若p的下一结点为空或找不到第i-1个结点,则报错
q = p->next; //q指向第i个结点
p->next = q->next; //p指向i的后继结点
delete q; //删除第i个结点
return ok;
}
5、编写算法,实现带头结点单链表的逆置算法(10分)
算法思路:
首先把头结拆下来,然后使用头插法的方式依次把每个结点倒序接入到头结点之后。
void Reverse_L(Linklist &L){
if(!p->next || !p->next->next) return; //若为空表或表长为1时不做处理
Lnode *p,*r;
p = L->next; //p指向首元结点
L->next = Null; //拆开头结点,指针域设为空
while(p!=Null){
r = p->next; //r暂存p的后继结点
p->next = L->next; //采用头插法,将p结点插入到头结点之后
L->next = p; //头结点始终指向新插入的结点
p = r; //结点插入完以后,p指向下一结点
}
}
6、编写算法,在单链表上查找给定值为x的结点的个数
int ListLength_x(LinkList &L,int i){
int i = 0; LNode *p; p=L; //定义计数器i,从单链表中从头向后查找值为x的结点
while(p!= Null){
if(p->data==x) //如果p的数据域的值为x
i++; //则计数器的记录+1
p=p->next; //p继续往后寻找
}
return i; //返回值x结点的个数
}
7、顺序表与单链表的主要区别如下