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