数据结构学习——栈和队列

数据结构学习记录DAY6 :栈和队列

栈和队列

内心OS:今天算是学的最轻松的一天了,有了之前的代码以及看了这么多天的“代码规范’总算是敲键盘翘起来轻松一点了,首先是我多少了解老师敲代码的顺序了,多少可以在老师开始之前做一点准备了。其次老师的命名方式我也大致了解了,这个对我来说是非常重要的一件事,因为我盲打的能力很差,所以命名看着键盘会让我轻松很多很多。终于不用在脑子和手之间做取舍拉!

今天的内容主要是两方面:栈和队列
首先讲的是栈:
栈的概念:从模型上来说,栈遵循先入后出FILO(first in last out)的原则,从操作上来说,只对栈顶元素进行操作

在使用上,栈的类型大致可分为以下两种

  • 链式栈
  • 顺序栈

从内存使用来分类,栈的类型有:

  • 动态栈(链式
  • 静态栈(顺序一般是

栈的实现

从学下来的角度说的话,代码太简单了,但是从记录的角度说的话,还是稍作copy吧

  • 顺序静态栈
#define SUCCESS 0
#define FAILURE -1

typedef int ElemType
struct stack{
	size_t size;//数量
	size_t cap;//容量
	Elemtype *elem;
}

typedef struct stack *ST;
//创建
ST create_stack();
//销毁
ST destroy_stack(ST list);
//容量及大小
size_t cap_stack(ST list);
size_t size_stack(ST list);
//判断空和满
bool empty_stack(ST list);
bool full_stack(ST list);
//向栈中压入元素
int push_stack(ST list, ElemType elem);
//弹出栈顶元素
int pop_stack(ST list, void* elem);
//查看栈顶元素
int peek_stack(ST list, ElemType *pelem);
//遍历栈
void foreach_stack(ST list, void (*foreach)(ElemType));

具体实现如下

ST create_stack(size_t cap)
{
	ST list = (ST)malloc(sizeof(struct stack) + cap*sizeof(ElemType));
	if(NULL != list)
	{
		list->cap = cap;
		list->size = 0;
	}
	return list;
}
//销毁
int destroy_stack(ST list)
{
	if(list != NULL)
	free(list);
	return SUCCESS;
}
//
size_t cap_stack(ST list)
{
	assert(NULL != list);
	return list->cap;
}
size_t size_stack(ST list)
{
	assert(NULL != list);
	return list->size;
}
//
bool empty_stack(ST list)
{
	assert(NULL != list);
	return list->size == 0;
}
bool full_stack(ST list)
{
	assert(NULL != list);
	return list->size == list->cap;
}
//向栈中压入元素
int push_stack(ST list, ElemType elem)
{
	assert(NULL != list);
	if(full_stack(list)){
		return FAILURE;
	}
	list->elem[list->size++] = elem;
	return SUCCESS;
}
int pop_stack(ST list, ElemType *elem)
{
	assert(NULL != list);
	if(empty_stack(list)){
		return FAILURE;
	}
	list->size--;
	if(elem != NULL)
	*elem = list->elem[list->size];
	return SUCCESS;
}
int peek_stack(ST list, ElemType *pelem)//查看栈顶元素
{
	assert(NULL != list && NULL != pelem);
	if(empty_stack(list)){
		return FAILURE;
	}
	*pelem = list->elem[list->size-1];
	return SUCCESS;
}

void foreach_stack(ST list, void (*foreach)(ElemType *pe))
{
	assert(list != NULL && foreach != NULL);
	int i;
	for(i = 0; i < list->size; ++i){
		foreach(&list->elem[i]);
	} 
}

链式栈:(逐渐变懒看看就好)

#define SUCCESS 0
#define FAILURE -1

struct _SNode{
	struct _SNode *next;
	char elem[];
};

#define _SNODESIZE sizeof(struct _SNode)

struct Stack{
	size_t elemSize;
	size_t size;
    struct _SNode *top;
};

typedef struct Stack *ST;
ST create_link(size_t elemSize)
{
    ST st = (ST)malloc(sizeof(struct Stack));
    if(NULL != st)
    {
        st->elemSize = elemSize;
        st->top = NULL;
        st->size = 0;
    }
    return st;
}
//
size_t size_linkstack(ST st)
{
    assert(NULL != st);
    return st->size;
}
//
bool empty_linkstack(ST st)
{
    assert(NULL != st);
    return st->size == 0;

}
//向栈中压入元素
int push_linkstack(ST st, void *elem){
    assert(NULL != st && elem != NULL);
    struct _SNode *node = (struct _SNode *)malloc(_SNODESIZE + st->elemSize);
    if(node == NULL)
    {
        return FAILURE;
    }
    node->next = st->top;
    st->top = node;
    memcpy(node->elem, elem, st->elemSize);
    ++st->size;
    return SUCCESS;

}
int pop_linkstack(ST st, void *elem)
{
    assert(NULL != st && elem != NULL);
    if(empty_linkstack(st))
    {
        return FAILURE;
    }
    struct _SNode *node = st->top;
    st->top = node->next;
    if(elem != NULL)
    {
        memcpy(elem, node->elem, st->elemSize);
    }
    free(node);
    --st->size;
    return SUCCESS;
}
//销毁
int clear_linkstack(ST st)
{
    assert(NULL != st);
    while(!empty_linkstack(st))
    {
        pop_linkstack(st,NULL);
    }
}
int destroy_linkstack(ST st)
{
    assert(NULL != st);
    clear_linkstack(st);
    free(st);
}
int peek_linkstack(ST st, void *pelem)//查看栈顶元素
{
    assert(NULL != st && pelem != NULL);
    if(empty_linkstack(st))
    {
        return FAILURE;
    }
    memcpy(pelem, st->top->elem, st->elemSize);
    return SUCCESS;
}

void foreach_linkstack(ST st, void (*foreach)(const void *p))
{
    assert(NULL != st && foreach != NULL);
    struct _SNode *node = st->top;
    for(;node!=NULL;node=node->next){
		foreach(&node->elem);
	}
}

栈的应用

  • 函数调用
    • 函数调用即把函数入栈,每次执行的函数都是栈顶的函数,执行后出栈
  • 走迷宫
  • 算数表达式求解
    • 前缀表达式: 运算符在操作数前面
    • 中缀表达式:运算符在操作数中间(3 + 4)* (5+6*2)
    • 后缀表达式:运算符在操作数后面 3 4 + 5 6 2 * + *
  • 八皇后问题
    • 回溯问题
  • 拆解正整数

以上内容均未实现

队列

队列的概念:从模型上来说,队列遵循先入先出FIFO(first in first out)的原则。一般都是用食堂打饭来做类比的,从操作上来说,比较复杂。由于是在队尾添加元素而队首弹出元素,那么就需要保存队首和队尾。现实中,出队之后的填充操作很容易,但是在计算机里,如果让食堂窗口位置保持不动,那么当一个元素出队后,后面的元素需要被动的向前补,非常浪费时间,所以我们采用一个元素出队后,让窗口向前移动的方法,象形起来很恐怖,但是计算机里只是修改了队首的值,非常的快捷。
然后由于在定义时,头和尾都在同一位置,如果采用头加尾的双指示来做的话,当队满时必须在尾的后面空置一个单位的内存,否则就会出现头和尾重合的情况,这样的话就和空队的情况相同了。但是循环队列就可以解决这一个内存浪费的问题,实现如下

#define SUCCESS 0
#define FAILURE -1


typedef int ElemType;
struct Queue{
    size_t cap;
    size_t head;//队列头下标
    size_t size;//(head+size-1)%cap 队尾
    ElemType elems[];
};

QE create_queue(size_t cap)
{
    QE queue = (QE)malloc(sizeof(struct Queue) + sizeof(ElemType)*cap);
    if(queue != NULL)
    {
        queue->cap = cap;
        queue->size = 0;
        queue->head = 0;
    }
    return queue;
}

bool empty_queue(QE queue)
{
    assert(NULL != queue);
    return queue->head == queue->size;
}

bool full_queue(QE queue)
{
    assert(NULL != queue);
    return queue->size == queue->cap;
}

size_t cap_queue(QE queue)
{
    assert(NULL != queue);
    return queue->cap;
}

size_t size_queue(QE queue)
{
    assert(NULL != queue);
    return queue->size;
}

void destroy_queue(QE queue)
{
    assert(NULL != queue);
    free(queue);
}

int front_queue(QE queue, ElemType *elem)
{
    assert(NULL != queue && elem != NULL);
    if(empty_queue(queue))
    {
        return FAILURE;
    }    
    *elem = queue->elems[queue->head];
    return SUCCESS;
}

int push_queue(QE queue, ElemType elem)
{
    assert(NULL != queue);
    if(full_queue(queue))
    {
        return FAILURE;
    }    
    queue->elems[(queue->size + queue->head) % queue->cap] = elem;
    ++queue->size;
    return SUCCESS;
}

int pop_queue(QE queue, ElemType *elem)
{
    assert(NULL != queue);
    if(empty_queue(queue))
    {
        return FAILURE;
    }    
    if(elem != NULL)
    {
        *elem = queue->elems[queue->head];
    }
    queue->head = (queue->head + 1)%queue->cap;
    --queue->size;
    return SUCCESS;
}

int back_queue(QE queue, ElemType *elem)
{
    assert(NULL != queue && elem != NULL);
    if(empty_queue(queue))
    {
        return FAILURE;
    }    
    *elem = queue->elems[(queue->size + queue->head - 1) % queue->cap];
    return SUCCESS;
}

void foreach_queue(QE queue, void (*foreach)(ElemType *pe))
{
    assert(queue != NULL && foreach != NULL);
	int i;
	for(i = 0; i < queue->size; ++i){
		foreach(&queue->elems[(queue->head + i) % queue->cap]);
	} 
}
#define SUCCESS 0
#define FAILURE -1

struct _Qnode
{
    struct _Qnode *next;
    char elems[];
};

#define _QNODESIZE sizeof(struct _Qnode)

struct Queue{
    size_t elemSize;
    struct _Qnode *head;//指向队首
    struct _Qnode *tail;//指向队尾巴
    size_t size;//(head+size-1)%cap 闃熷熬
};
QE create_queue(size_t elemsize)
{
    QE queue = (QE)malloc(sizeof(struct Queue));
    if(queue != NULL)
    {
        queue->elemSize = elemsize;
        queue->head = NULL;
        queue->tail = NULL;
        queue->size = 0;
    }
    return queue;
}

bool empty_queue(QE queue)
{
    assert(NULL != queue);
    return queue->head == NULL;
}

bool full_queue(QE queue)
{
    assert(NULL != queue);
    return queue->tail == queue->head;
}

size_t size_queue(QE queue)
{
    assert(NULL != queue);
    return queue->size;
}

void clear_queue(QE queue)
{
    assert(NULL != queue);
    /*
    while(empty_queue(queue))
    {
        pop_queue(queue);
    }*/
    struct _Qnode *node, *next;
    for(node = queue->head; node != NULL; node = next)
    {
        next = node->next;
        free(node);
    }
    queue->head = NULL;
    queue->tail = NULL;
    queue->size = 0;

}

void destroy_queue(QE queue)
{
    assert(NULL != queue);
    clear_queue(queue);
    free(queue);
}

int front_queue(QE queue, void *elem)
{
    assert(NULL != queue && elem != NULL);
    if(empty_queue(queue))
    {
        return FAILURE;
    }
        memcpy(elem, queue->head->elems, queue->elemSize);
    return SUCCESS;
}

int push_queue(QE queue, void *elem)
{
    assert(NULL != queue && elem != NULL);
    struct _Qnode *node = (struct _Qnode*)malloc(_QNODESIZE + queue->elemSize);
    if(NULL == node)
    {
        return FAILURE;
    }
    node->next = NULL;
    memcpy(node->elems, elem, queue->elemSize);
    printf("88");
    if(queue->tail != NULL)
    {
        queue->tail->next = node;
    }
    else
    {
        queue->head = node;
    }

    queue->tail = node;
    ++queue->size;
    return SUCCESS;
}

int pop_queue(QE queue, void *elem)
{
    assert(NULL != queue && elem != NULL);
    if(empty_queue(queue))
    {
        return FAILURE;
    }
    struct _Qnode *node = queue->head;
    if(NULL != elem)
    {
        memcpy(elem, node->elems, queue->elemSize);
    }
    queue->head = node->next;
    if(node == queue->tail)
    {
        queue->tail = NULL;
    }
    free(node);
    --queue->size;
    return SUCCESS;
}

int back_queue(QE queue, void *elem)
{
    assert(NULL != queue && elem != NULL);
    if(empty_queue(queue))
    {
        return FAILURE;
    }
    memcpy(elem, queue->tail->elems, queue->elemSize);
    return SUCCESS;
}

void foreach_queue(QE queue, void (*foreach)(const void *))
{
    assert(NULL != queue && foreach != NULL);
    struct _Qnode *node;
    for(node = queue->head;node!=NULL;node=node->next){
		foreach(node->elems);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值