2022.9.21实训笔记

107 阅读4分钟

链表实现栈

入栈

bool Push(LinkStack *head,ElemType e){
	LinkStack *s = (LinkStack *)malloc(sizeof(LinkStack));
	s->data = e;
	s->next=head->next;
	head->next=s;
	return true;
}

出栈

bool Pop(LinkStack *head,ElemType &x){
	//判栈空
	if(head->next == null){
		return false; 
	}
	LinkStack *q=head->next;
	x =q->data;
	head->next=q->next;
    free(q);
	return true;
}

有n个人围成一圈,顺序排号,从第一个人开始报数,凡报到3的人退出圈子,问最后留下的是原来第几号的那位?

struct node
{
int num;
struct node *next;
};
struct node *head;
struct node *last;
void cre_list()
{
head = (struct node *)malloc(sizeof(struct node));
last = head;
head->next = head;
}
void display_node()
{
struct node *ptr = head->next;
while(ptr != head)
{
printf("%d\t",ptr->num);
ptr = ptr->next;
}
printf("\n");
}
void add_node(int num)
{
struct node *ptr = (struct node *)malloc(sizeof(struct node));
ptr->num = num;
ptr->next = head;

last->next = ptr;
last = ptr;
}
void rev_node()
{
struct node *ptr = head;
last->next = head->next;
head = head->next;
free(ptr);
}
void tiren_node()
{
struct node *ptr = head;
struct node *str = ptr->next;
struct node *qtr = str->next;
while(ptr->next != ptr)
{
str = ptr->next;
qtr = str->next;
str->next = qtr->next;
ptr = str->next;
}
printf("%d\n",ptr->num);
}
int main()
{
int i = 0;
cre_list();
int n;
printf("please input n:\n");
scanf("%d",&n);
printf("%d\n",n);
for(i = 1;i <= n;i++)
{
add_node(i);
}
display_node();
rev_node();
tiren_node();
return 0;
}

队列解决报3问题

image.png

队列

队列(Queue)。队列简称队。是一种操作受限的线性表,只允许在表的一端进行插入,而在表的另一端进行删除。向队列中插入元素称为入队或进队;删除元素称为出队或离队。其操作特性为先进先出(First In First Out,FIFO),并且只允许在队尾进,队头出。

队列的顺序实现市值分配一块连续的存储单元存放队列中的元素,并附设两个指针 front 和 rear 分别指示队头元素和队尾元素的位置。设队头指针指向队头元素,队尾指针指向队尾元素的下一个位置。

#define MAXSIZE 100
typedef struct {
    ElemType data[MAXSIZE];
    int front,rear;
} SqQueue;

初始状态(队空):Q.front == Q.rear == 0;

进队操作:队不满时,先送值到队尾元素,将队尾指针加1

出队操作:队非空时,先删除队头元素,再将队头指针加1

由上可知,Q.front == Q.rear == 0 可以作为队列的判空条件,但能否能用 Q.rear == MAXSIZE 作为队列已满的条件呢?显然是不行的,因为队尾指针可能已经到了最尾端,但是队头指针可能不在初始位置,而是在队列的中间,这时入队出现“上溢”,但这种溢出并不是真正的溢出,data数组中仍存在可以放置元素的位置,所以为“假溢出”。

循环队列

将队列想象成一个环状的空间,即把存储队列元素的表从按逻辑上视为一个环,称为循环队列。当队首指针 Q.front == MAXSIZE - 1,再前景一个位置就自动到0,这可以利用除法取余运算(%) 来实现。

初始化时:Q.front = Q.rear = 0;

队首指针进1:Q.front = (Q.front + 1) % MAXSIZE;

尾指针进1:Q.rear = (Q.rear + 1)% MAXSIZE;

队列长度:(Q.front + MAXSIZE - Q.rear) % MAXSIZE;

循环队列如何判断队满还是队空?

  1)一般的做法是:入队时少入对一个队列单元,约定“队尾指针的下一个标志是队头指针 作为 队满的标志“:

    队空条件:Q.front == Q.rear

    队满条件:(Q.rear + 1) % MAXSIZE == Q.front

    队列长度:(Q.rear - Q.front + MAXSIZE )% MAXSIZE

  2)在类型中添加表示成员个数的数据成员。队空时 Q.size == 0;队满时 Q.size == MAXSIZE

  3)类型中添加tag 数据成员,以区分是队满还是对空。tag ==0 ,若因删除导致Q.front == Q.rear ,则为队空;若tag == 1,若因添加导致Q.front == Q.rear,则为队满。

判断队空

bool QueueEmpty(SqQueue Q){
    if( Q.front == Q.rear){
        return true;
    }
    return false;
}

入队

bool EnQueue(SqQueue& Q, ElemType x){
    if( (Q.rear + 1) % MAXSIZE == Q.front ){
        return false;
    }
    Q.data[Q.rear] = x;
    Q.rear = ( Q.rear + 1) % MAXSIZE;//队尾指针加1取模,这步操作很容易写错
    return true;    
}

出队

bool DeQueue(SqQueue& Q, ElemType &x){
    if( Q.rear == Q.front ){
        return false;
    }
    x = Q.data[Q.front];
    Q.front = (Q.front + 1) % MAXSIZE;//队头指针加1取模
    return true;
}

@PI0Y6LTA1)IQ3PT$G{SG%R.png

image.png

H(FJNE57`YOW~U4OD4PL28Q.png

image.png

C++

作为一种面向对象的编程语言,C++ 支持多态、封装和继承。 C++ 支持面向过程和面向对象的编程范式

在 C++ 中,封装隐藏数据以确保按预期使用数据结构和运算符。

C++ 使用 NAMESPACE 来避免名称冲突。

命名空间是一个声明性区域,为其中的标识符(类型、函数、变量等的名称)提供范围。命名空间用于将代码组织成逻辑组并防止可能发生的名称冲突,尤其是当您的代码库包含多个库时。命名空间范围内的所有标识符彼此可见,无需限定。命名空间之外的标识符可以通过使用每个标识符的完全限定名称来访问成员。

C++ 提供对异常处理的支持。异常用于使代码不正确的“硬”错误。