哈佛大学公开课:计算机科学cs50 学习笔记及代码练习(第14集:栈,队列,哈希表,树)

周末写代码

--------------------------------2018.8.7---------------------------

1. stack

stack 后进先出(LIFO)结构。下面用数组实现栈,用malloc使栈的容量可扩展。

stack.c

这里要特别注意:

(1) Destroy()函数中,free(s->data); 以及 s->data = NULL; 否则出现野指针。因为在Init()中用了malloc;

(2) 另外,取栈顶元素 Top() 函数 不要用返回值,因为如果栈空就没有元素可以返回。用指针传参好了: void Top(Stack *s, datatype * topElement)

(3) 初始化函数 bool Init()要加入判断条件,判断s->data 是否是NULL,因为malloc 若在heap里面分配内存不成功就返回NULL,因此初始化函数也返回bool,初始化不成功返回false

#include "stack.h"
#include <stdio.h>

static int realsize = MAXSIZE;
 
// initialize the stack
bool Init(Stack *s)
{
    s->data = (datatype *)malloc(sizeof(datatype) * MAXSIZE);
    s->top = -1;
    if (s->data != NULL)
        return true;
    else
        return false;
}
 
// is the stack empty?
bool isEmpty(Stack *s)
{
    if(s->top == -1)
    {
        return true;
    }
    else
    {
        return false;
    }
}
 
// enlarge the capacity of the stack
void enlarge(Stack *s)
{
    if(s->top == realsize - 1)
    {
        realsize *= 2;
        s->data = (datatype *)realloc(s->data, realsize * sizeof(datatype));
    }
}
 
// push element into the stack
void Push(Stack *s, datatype element)
{
    enlarge(s);
    s->top++;
    s->data[s->top] = element;
}
 
// pop element out of the stack
void Pop(Stack *s)
{
    if(!isEmpty(s))
    {
        s->top--;
    }
    else
    {
        printf("stack is empty, can not be poped!\n");
    }
}
 
// get the top element of the stack
void Top(Stack *s, datatype * topElement)
{
    if(!isEmpty(s))
    {
        *topElement = s->data[s->top];
    }
    else
    {
        printf("stack is empty, no top element!\n");
    }
}
 
// destroy the stack
void Destroy(Stack *s)
{
    s->top = -1;
    free(s->data); 
    s->data = NULL;
}

stack.h

#ifndef STACK_H
#define STACK_H

#include<stdbool.h>
#include<stdlib.h>

#define MAXSIZE 10

typedef int datatype;

//Sequence Stack 
typedef struct stack
{
    datatype *data; // array
    int top;
} Stack;


// initialize the stack
bool Init(Stack *s);

// is the stack empty?
bool isEmpty(Stack *s);

// enlarge the capacity of the stack
void enlarge(Stack *s);

// push element into the stack
void Push(Stack *s, datatype element);

// pop element out of the stack
void Pop(Stack *s);

// get the top element of the stack
void Top(Stack *s, datatype * topElement);

// destroy the stack
void Destroy(Stack *s);


#endif

main.c

#include "stack.h"
#include <stdio.h>

int main(void)
{
    // build a stack
    Stack * s = (Stack*)malloc(sizeof(Stack));
    // initialize the stack
    if (!Init(s))
        return 1;
    // is empty?
    if (isEmpty(s))
        printf("stack is empty \n");
    else
        printf("stack is not empty \n");
    // push 22 elements into the stack
    for (datatype i = 0; i < 22; ++i)
        Push(s, i);
    
    // what is the top element
    datatype i = -1;
    datatype * topElement = &i;
    Top(s, topElement);
    printf("%d\n", *topElement);
    // pop 10 elements out of the stack
    for (datatype i = 0; i < 10; ++i)
        Pop(s);
    // what is the top element of the stack now?
    i = -1;
    Top(s, topElement);
    printf("%d\n", *topElement);
    // destroy the stack
    Destroy(s);
    // what is the top element of the stack now?
    i = -1;
    Top(s, topElement);
    printf("%d\n", *topElement);


    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(stack)

add_compile_options(-std=c11)

add_executable (stack main.c stack.c)

结果如下:

2. Queue 队列

队列是先进先出(FIFO)结构。下面用链表实现队列

queue.c

#include "queue.h"
#include <stdlib.h>

// initialize a queue
void InitQueue(Queue* queue)
{
    if (queue == NULL)
        return;
    queue->tail = (Node*)malloc(sizeof(Node));
    if (queue->tail == NULL)
        return;
    queue->tail->data = -1;
    queue->head = queue->tail;
    queue->tail->next = NULL;
}

// push a element into the queue
void PushQueue(Queue* queue, datatype data)
{
    if (queue == NULL)
        return;
    Node * newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL)
        return;
    newNode->data = data;
    newNode->next = NULL;
    queue->tail->next = newNode;
    queue->tail = newNode;
}

// pop a element out of the queue
void PopQueue(Queue* queue)
{
    if (queue == NULL)
        return;
    if (IsEmpty(queue))
        return;
    datatype popValue = queue->head->data;
    Node *popNode = queue->head;
    queue->head = queue->head->next;
    free(popNode);
    popNode = NULL;
}

// is the queue empty?
bool IsEmpty(Queue* queue)
{
    return (queue->head == queue->tail);
}

// destroy the queue
void DestroyQueue(Queue* queue)
{
    if (queue == NULL)
        return;
    while(!IsEmpty(queue))
    {
        PopQueue(queue);
    }
    free(queue->tail);
    // free(queue->head);
}

// print the queue
void PrintQueue(Queue* queue)
{
    if (queue == NULL)
        return;
    if(IsEmpty(queue))
    {
        printf("empty queue.\n");
        return;
    }
    Node* curNode= queue->head->next;
    while(curNode)
    {
        if (curNode->next !=NULL)
            printf("%d==>", curNode->data);
        else
            printf("%d ", curNode->data);
        curNode = curNode->next;
    }
    printf("\n");
}

queue.h

#ifndef QUEUE_H
#define QUEUE_H


#include <stdio.h>
#include<stdbool.h>

typedef int datatype;

typedef struct node
{
    datatype data;
    struct node* next;
} Node;

typedef struct queue
{
    Node* head;
    Node* tail;
} Queue;

// initialize a queue
void InitQueue(Queue*);

// push a element into the queue
void PushQueue(Queue*, datatype);

// pop a element out of the queue
void PopQueue(Queue* queue);

// print the queue
void PrintQueue(Queue* queue);

// is the queue empty?
bool IsEmpty(Queue* queue);

// destroy the queue
void DestroyQueue(Queue* queue);


#endif

main.c

#include "queue.h"
#include <stdlib.h>


int main(void)
{
    Queue * queue = (Queue*)malloc(sizeof(Queue));
    InitQueue(queue);

    for (datatype i = 0; i != 4; ++i)
        PushQueue(queue, i);
    
    PrintQueue(queue);

    PopQueue(queue);

    PrintQueue(queue);

    for (int i = 0; i != 10; ++i)
        PopQueue(queue);

    PrintQueue(queue);

    for (datatype i = 0; i != 5; ++i)
        PushQueue(queue, i);

    PrintQueue(queue);

    DestroyQueue(queue);

    PrintQueue(queue);

    free(queue);
    queue = NULL;
    
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(stack)

add_compile_options(-std=c11)

add_executable (stack main.c stack.c)

结果:

猜你喜欢

转载自blog.csdn.net/shaozhenghan/article/details/81494656
今日推荐