第三章 表、栈和队列(四)栈的实现以及平衡符号的实现

用list.h实现栈,编写平衡符号代码、后缀表达式代码,中缀和后缀表达式的转换。

主要是对list.h的封装,list.h满足堆和队列的一切操作,stack是list的子集

遇到的问题:

typedef struct list_head *Stack;

struct balance_char 
{
    char c;
    Stack s;
};

#define stack_entry(ptr, type, member) \
	container_of(ptr, type, member)

int main()
{
    CheckChar first, temp,temp1,d;
    char test[] = "{dfssf[fdg(fg)fsghjk]gjy}";
    int m;

    first = init_char('\0');
    d = init_char('d');
    
    list_add(d->s,first->s);
    
    temp = stack_entry(&(first->s->next), struct balance_char, s);
    temp1 = stack_entry(&d->s, struct balance_char, s);
    
    printf("%c\n", temp->c);
    printf("%c\n", temp1->c);

    printf("first->s->next=%p\n", first->s->next);
    printf("d->s=%p\n", d->s);
    printf("&first->s->next=%p\n", &first->s->next);
    printf("&d->s=%p\n", &d->s);

}

first->s->next=0x55e7dd0702c0
d->s=0x55e7dd0702c0
&first->s->next=0x55e7dd070288
&d->s=0x55e7dd0702a8

直接把Stack定义为指针类型,导致stack_entry失效,原因是需要通过s所在地址找到balance_char的地址。

虽然first堆栈中next指向的地址是d的stack地址。但是&first->s->next和&d->s的却不同,因为存放0x55e7dd0702c0

地址的变量一个是first->s->next,一个是d->s,他们也s变量都进行过malloc,内存位置必然不一样。

因此把Stack定义为非指针,next直接保存变量的地址。以后会到hlist也有类似的操作。

 

栈的实现:

int stack_empty(const Stack s)
{
	return (s.next == &s);
}

ptr_node pop(Stack s)
{
    ptr_node top;
    if(!stack_empty(s))
    {
      top = s.next;
      list_del_init(top);
    }
    return top;
}

//s1压栈的栈内容
//s2被压栈的栈,这是一个把大块的栈压到另一个栈的代码
//操作系统压栈线程估计会用到
void push_block(Stack *s1, Stack *s2)
{
    list_splice_init(s1,s2);
}

void push(Stack *s1, Stack *s2)
{
    list_add(s1,s2);
}

平衡符号代码:

CheckChar init_char(char c)
{
    CheckChar tempcell;
    tempcell = malloc(sizeof(struct balance_char));
    tempcell->c = c;
    tempcell->s.next = &tempcell->s;
    tempcell->s.prev = &tempcell->s;
    return tempcell;
}

void pop_char(CheckChar check)
{
    ptr_node ptr;
    ptr = pop(check->s);
    free(stack_entry(ptr, struct balance_char, s));
}

void del_char_stack(CheckChar check)
{
    if(!stack_empty(check->s))
        pop_char(check);
}

CheckChar push_char(CheckChar check, CheckChar head)
{
    list_add(&check->s, &head->s);
}

CheckChar top(CheckChar check)
{
    if(!stack_empty(check->s))
    {
        return stack_entry(check->s.next, struct balance_char, s);
    }
    return NULL;
}

int check_char(char *s, int size)
{
    CheckChar check,first,tempcel,pos;
    int num;
    int res = 0;
    first = init_char('a');
    for(num = 0; num < size; num++)
    {
        if(s[num] == '{' || s[num] == '[' || s[num] == '(')
        {
            check = init_char(s[num]);
            push(&check->s, &first->s);
        }
        else if(s[num] == '}' || s[num] == ']' || s[num] == ')')
        {
            tempcel = top(first);
            if((s[num] == '}' && tempcel->c != '{') \
            || (s[num] == ']' && tempcel->c != '[') \
            || (s[num] == ')' && tempcel->c != '('))
            {
                res = 0;
                del_char_stack(first);
                return res; 
            }
            else
            {
                pop_char(first);
            }    
        }        
    }
    res = 1;
    del_char_stack(first);
    free(first);
    return res;
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值