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