[Data structure] A shuttle for the midterm exam (on the overnight version)

foreword

红中(Hong_zhong)
CSDN内容合伙人、2023年新星计划web安全方向导师、
吉林师范大学网安大一的一名普通学生、摸鱼拿过大挑校二、
华为MindSpore截至目前最年轻的优秀开发者、IK&N战队队长、
阿里云专家博主、华为网络安全云享专家、腾讯云自媒体分享计划博主、

After paddling for half a semester, the data structure midterm exam for C will be tomorrow afternoon.

As we all know, let me learn C == let me s->True.

No way, I learned the data structure of Python and directly learned to sort and search binary trees. These things are still in the next few chapters.

I have never heard of linked lists.

I just want not to hang up and simply stay up all night.

open

linked list

Initial Impressions of Linked Lists

Linked list, that is, a chained storage structure.

 DATA is our custom data type, and NEXT is a pointer to the next linked list. When we visit NEXT, we are guided to the position of the next node in the linked list.

The abstract point is similar to the train carriage

 The front of a car is a node, the back is a pointer, and the middle connection is the position pointed by the pointer.

The difference between linked list and array

Compared with arrays, operations such as insertion and deletion become easier.

Why do you say that?

For example, now there is such an array:

[1,2,3,4,5,6,7,8]

I want to insert a "9" after "1", which means that all elements after "1" need to be moved back one bit, and then a new memory space is made, and "9" is inserted. Die in trouble

But if it is a linked list, let’s talk about it abstractly first. If you want to add a section between train cars, you only need to untie the chain between the cars, hang the rear ones on the new car first, and then hang the front ones, and you’re done.

There is no need to adjust the whole/most of the data, just change the DATA pointed by the pointer, which is really convenient.

However, this thing takes up more than a little bit more than the array (it's really hard to write

Common types of linked lists

Singly linked list, double linked list, circular singly linked list

 Image source: To understand the "linked list" in one breath, rely on these 20+ pictures-Knowledge

Single list

Code expression of the concept of singly linked list:

typedef struct Node{//定义单链表的结点类型
    int data;//数据域,随便写哪种类型都可以
    struct Node *next;//指针域
    }Node,*LinkList;//Node表示结点的类型,LinkedList表示指向Node结点类型的指针类型

Initialization of linked list

LinkedList listinit(){
    Node *L;
    L=(Node*)malloc(sizeof(Node));//申请开辟空间
    if(L==NULL){
        printf("申请失败");//判断是否开辟成功
    }
    L->next=NULL;//指针指向NULL
}

We don't know what the application for opening up the space is, just memorize it and it's over.

head insertion

This thing is actually quite understandable

Prepare a picture using s

 This is a node that plugs in and plugs in from the head. Suppose I come to another node, that is, I can point the pointer of the new node to the DATA of the original node. The original node is always in the back, that is, the order of the entire linked list is reversed at the end.

Code:

LinkedList LinkedListCreate(){
    Node *L;
    L=(Node *)malloc(sizeof(Node));
    L->next=NULL;

    int x;//x为链表中的数据
    while (scanf("%d",&x!=EOF)){
        Node *p;//定义p的指针域
        p=(Node *)malloc(sizeof(Node));//申请空间
        p->data=x;//将x赋给p节点的数据域
        p->next = L->next;//将头指针所指向的下一个结点的地址,赋给新创建结点的next 
        L->next = p;//将新创建的结点的地址赋给头指针的下一个结点
       }
    return L;
}

tail plugging

The same understanding of the tail insertion method, the pointer of the original node points to the DATA field of the new node.

Do not explain, write code directly:

LinkedList LinkedListCreate(){
    Node *L;//申请指针域
    L=(Node *)malloc(sizeof(Node));//申请头节点空间
    L->next=NULL;//初始化一个空链表
    Node *r;
    r=L;//r始终指向尾节点,开始时指向头节点
    int x;//x为链表DATA中的数据
    while (scanf("%d",&x)!=EOF){
        Node *p;//申请指针域
        p=(Node *)malloc(sizeof(Node));//申请新的节点
        p->data=x;
        r->next=p;
        r=p;//r始终指向尾节点
    }
    r=next=NULL;
    return L;
}

Revise

LinkedList LinkedListReplace(LinkedList L,int a,int b) {
    Node *p=L->next;//定义指针域指向节点指针指向
    int i=0;
    while(p){
        if(p->data==a){//如果p节点数据域中的值等于a
            p->data=b;//将p节点数据域中的值a改成b
        }
        p=p->next;//节点指针依旧指向后面
    }
    return L;
}

insert

LinkedList LinkedListInsert(LinkedList L,int i,int x) {
    Node *pre;                      //pre为前驱结点
    pre = L;
    int tempi = 0;
    for (tempi = 1; tempi < i; tempi++) {
        pre = pre->next;                 //查找第i个位置的前驱结点
    }
    Node *p;                                //插入的结点为p
    p = (Node *)malloc(sizeof(Node));
    p->data = x;//给p赋个值
    p->next = pre->next;//将前驱节点之前指向的地址赋给插入节点并让其指向
    pre->next = p;//将前驱节点指针指向引导到新节点头上
  
    return L;
}

delete

LinkedList LinkedListDelete(LinkedList L,int x) {
    Node *p,*pre; //pre为前驱结点,p为查找的结点。
    p = L->next;
     
    while(p->data != x) {//查找值为x的元素
        pre = p;
        p = p->next;
    }
    pre->next = p->next;//删除操作,将其前驱next指向其后继。
    free(p);//free函数释放掉
     
    return L;
}

If you don't write the double-linked list, bet he won't take the test.

exercise

 The first question and the second question: Just give a few deduction algebras.

The third question is directly brought. The fourth question, look at the picture

True - use s

 Topic 5: Involving Concepts

Storage density, in the computer, refers to the ratio of the storage amount occupied by the node data itself to the storage amount occupied by the entire node structure. The calculation formula is: storage density = (storage amount occupied by the node data itself) / (knot the total amount of storage occupied by point structures)

 Question 6: A brief understanding of the sequence table

 Question 10/11: The leading single-linked list means that the pointer field points to empty, and it is empty if it is not leading.

I don't feel like I have anything to say, just fill in the blank and see

 

 It is easy to pass the knowledge point, there is no difficulty,

the stack

Principle/Concept

I have learned the Python stack before, briefly talk about the principle, look at the code implementation, and do some questions.

The stack is something like a barrel bookshelf.

At first the bookshelf was empty, we put a copy of "Postpartum Care of Sows" inside, well, there is already a book in the stack

Now let's put another copy of "How I Ruined My Life Because of CTF", and now there are two books in the stack

 If we want to watch "Postpartum Care of Sows", but we can't directly pull it out from the bottom of the stack, we can only put the

Take out "How I Ruined My Life Because of CTF" and get the book we want.

Then the order here is a characteristic of a stack: first in last out

Anyway, I just remember this one, and I can’t say anything more, just look at the code implementation.

Code

not difficult

empty square

void InitStack(SeqStack *S){
    S->top=-1;
}

Determine if the stack is empty

int EmptyStack(SeqStack * S){
    if (S->top<0)
        return 1;//为空栈
    else
        return 0;//不为空栈
}

push

int Push(SeqStack * S,DataType x){
    if (S->top>=MAXSIZE-1)//
    {    printf("栈满不能进栈");
         return 0;
    }
    S->top++;//移动栈顶指针
    S->data[S->top]=x;//元素x进栈
    return (1);
}
        

pop out

It's about the same as stacking

int Push(SeqStack * S){
    if (S->top《=MAXSIZE-1)//
    {    printf("栈空不能出栈");
         exit(0);
    }
    x=S->data[S->top]//将栈顶值保存至x
    S->top--;//移动栈顶指针
    return (x);
}
        

read the top element of the stack

DataType GetTop(LinkStack * Top)

{
    if (Top == NULL)
        printf("\n栈空");
    else
        return Top->data;
}

Full code and example:

#include<bits/stdc++.h>
using namespace std;

#define MaxSize 100 //定义栈中元素的最大个数
typedef struct SqStack{
    int data[MaxSize]; //存放栈中的元素
    int top; //栈顶指针
}SqStack;

//初始化
void InitStack(SqStack &S){
    S.top = -1;
}

//判栈空
bool Empty(SqStack S){
    if(S.top == -1){
        return true;
    }else{
        return false;
    }
}

//入栈
void Push(SqStack &S, int x){
    if(S.top == MaxSize-1){
        cout<<"栈满"<<endl;
        return;
    }
    S.data[++S.top] = x;
}

//出栈
void Pop(SqStack &S, int &x){
    if(S.top == -1){
        cout<<"栈空"<<endl;
        return;
    }
    x = S.data[S.top--];
}

//读栈顶元素
int GetTop(SqStack S){
    if(S.top == -1){
        cout<<"栈空"<<endl;
        return -1;
    }else{
        return S.data[S.top];
    }
}

//遍历栈
void PrintStack(SqStack S){
    while(S.top != -1){
        cout<<S.data[S.top--]<<" ";
    }
    cout<<endl;
}

//销毁栈
void DestroyStack(SqStack &S){
    S.top = -1;
}

int main(){
    SqStack S;
    InitStack(S);
    Push(S,1);//入栈
    Push(S,2);
    Push(S,3);
    Push(S,4);
    cout<<"栈顶元素为:"<<GetTop(S)<<endl;
    cout<<"出栈顺序为:";
    PrintStack(S);
    int x;
    Pop(S,x);
    cout<<x<<"出栈"<<endl;
    cout<<"栈中剩余元素:";
    PrintStack(S);
    Pop(S,x);
    cout<<x<<"出栈"<<endl;
    cout<<"栈中剩余元素:";
    PrintStack(S);
    if(!Empty(S)){
        cout<<"当前栈不为空"<<endl;
    }else{
        cout<<"当前栈为空"<<endl;
    }
    return 0;
}

From the stack - the definition and basic operations of the stack (initialization, empty judgment, push into the stack, pop out of the stack, traverse the stack, destroy the stack, etc.)_Schrödinger's cat ovo's blog-CSDN blog w

 I'm stupid and can't write.

exercise

 The characteristics of the first question, the top of the stack for the second question.

Although the chain stack is not mentioned, learning through the linked list is almost the same.

There is a problem with the third question. For the fourth question, first save the value in x, and then change the pointer field.


Who knows the family members, I will write tomorrow, I am tired

Guess you like

Origin blog.csdn.net/m0_55400802/article/details/130210260