第三章 表、棧和隊列(四)棧的實現以及平衡符號的實現

用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;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章