一,企业级链表的设计
数据结构的设计
//链接链表的指针
struct LinedNode
{
struct LinedNode* next;
} LinedNode;
//保存链表的信息
struct LList
{
struct LinedNode toppoter;
int m_size;
}LList;
typedef void* ListNode;
1,链表的初始化
ListNode Init_LinedNode()
{
//1,创建指针链表
struct LList* mylist = (struct LList*)malloc(sizeof(struct LList));
if (!mylist) return NULL;
mylist->m_size = 0;
mylist->toppoter.next == NULL;
return mylist;
}
2,插入数据 , 链接链表
void Insert_LinedNodeData(ListNode list, int pos, void* data)
{
//1,判断条件
if (!list) return; if (!data) return;
//2,位置的定位
struct LList* mylist = list;
if (pos < 0 || pos > mylist->m_size - 1)
pos = mylist->m_size;
//数据的指针区
struct LinedNode* newData = (struct LinedNode*)data;
struct LinedNode* ParentNode = &mylist->toppoter;
//3,插入的数据链接链表
int i;
for (i = 0; i < pos; i++)
ParentNode = ParentNode->next;
newData->next = ParentNode->next;
ParentNode->next = newData;
//改变链表的信息
mylist->m_size++;
}
3,打印链表信息
void Foreach_LinedNodeData(ListNode* list, void (*MyForeach)(void*))
{
//判断条件
if (!list) return; if (!MyForeach) return;
struct LList* mylist = list;
//取地址就打印不出第一元素了
struct LinedNode* ParentNode = mylist->toppoter.next;
int i;
for (i = 0; i < mylist->m_size; i++)
{
MyForeach(ParentNode);
ParentNode = ParentNode->next;
}
}
4,删除数据的操作
void Remove_LinedNodeData(ListNode list, int pos)
{
//1,条件判断
if (!list) return;
struct LList* mylist = list;
if (pos < 0 || pos > mylist->m_size - 1)
return;
struct LinedNode* PCurent = &mylist->toppoter;
int i;
for (i = 0; i < pos; i++)
PCurent = PCurent->next;
struct LinedNode* nextNode = PCurent->next;
PCurent->next = nextNode->next;
//更新链表的信息
mylist->m_size--;
}
5,销毁链表
void Destroy_LinedNode(ListNode list)
{
if (!list) return;
struct LList* mylist = (struct LList*) list;
free(mylist);
mylist == NULL;
}
* 测试一个数据*
struct Postion
{
struct LinedNode lNode;
char name[64];
int age;
} Postion;
void MyPrintf(void* data)
{
struct Postion* d = (struct Postion*)data;
printf("%s %d\n", d->name, d->age);
}
void test()
{
struct Postion p1 = { NULL, "aaa1", 10 };
struct Postion p2 = { NULL, "aaa2", 20 };
struct Postion p3 = { NULL, "aaa3", 30 };
struct Postion p4 = { NULL, "aaa4", 40 };
ListNode list = Init_LinedNode();
Insert_LinedNodeData(list, 10, &p1);
Foreach_LinedNodeData(list, MyPrintf);
Insert_LinedNodeData(list, 0, &p2);
Foreach_LinedNodeData(list, MyPrintf);
Insert_LinedNodeData(list, 0, &p3);
Foreach_LinedNodeData(list, MyPrintf);
Insert_LinedNodeData(list, 0, &p4);
Foreach_LinedNodeData(list, MyPrintf);
printf("--------------------------\n");
Foreach_LinedNodeData(list, MyPrintf);
Remove_LinedNodeData(list, 2);
printf("--------------------------\n");
Foreach_LinedNodeData(list, MyPrintf);
printf("--------------------------\n");
Destroy_LinedNode(list);
}
运行的结果图片
二,栈上的链表结构
数据结构的设计
#define MAX 1024
struct Stack
{
void* arr[MAX];
int m_size; //栈的大小
} Stack;
1,栈的初始化
SeqStack Init_SStack()
{
//开辟内存保存数组的信息
struct SStack* _stack = (struct SStack*)malloc(sizeof(struct SStack));
if (!_stack) return;
//初始化数据
memset(_stack->data, 0, MAX);
_stack->m_size = 0;
return _stack;
}
2,插入数据到栈中
void push_SStack(SeqStack _stack, void* data)
{
//1,条件判断
if (!_stack) return; if (!data) return;
//2,判断栈的空间是否足够
struct SStack* _Sstack = _stack;
if (_Sstack->m_size >= MAX) return;
//3,插入数据
_Sstack->data[_Sstack->m_size] = data;
//4,改变栈的信息
_Sstack->m_size++;
}
3,栈的弹出
void pop_SStack(SeqStack _stack)
{
//1,条件判断
if (!_stack) return;
struct SStack* _sstack = _stack;
//2判断数组中是否有元素
if (_sstack->m_size <= 0) return;
//3,弹出一个元素
_sstack->data[_sstack->m_size - 1] = NULL;
//更新栈中的信息
_sstack->m_size--;
}
4,弹出栈信息
void* top_SStack(SeqStack _stack)
{
//1,条件判断
if (!_stack) return;
struct SStack* _sstack = _stack;
//2判断数组中是否有元素
if (_sstack->m_size <= 0) return;
return (_sstack->data[_sstack->m_size - 1]);
}
5,查看栈是否有元素
int get_SStack(SeqStack _stack)
{
//1,条件判断
if (!_stack) return NULL;
struct SStack* _sstack = _stack;
//2判断数组中是否有元素
if (_sstack->m_size <= 0) return NULL;
return (_sstack->m_size);
}
6,清空数据
int Empty_SStack(SeqStack _stack)
{
//1,条件判断
if (!_stack) return;
struct SStack* _sstack = _stack;
//2判断数组中是否有元素
if (_sstack->m_size <= 0) return -1;
_sstack->m_size = 0;
_sstack->data[0] == NULL;
return -1;
}
7,销毁栈
void Destroy_SStack(SeqStack _stack)
{
//1,条件判断
if (!_stack) return;
struct SStack* _sstack = _stack;
//2判断数组中是否有元素
if (_sstack->m_size < 0) return;
free(_sstack);
_sstack = NULL;
}
下面是测试数据
struct Postion
{
char name[64];
int age;
} Postion;
void MyPrintf(void* data)
{
struct Postion* d = (struct Postion*)data;
printf("%s %d\n", d->name, d->age);
}
void test()
{
struct Postion p1 = { "aaa1", 10 };
struct Postion p2 = { "aaa2", 20 };
struct Postion p3 = { "aaa3", 30 };
struct Postion p4 = { "aaa4", 40 };
SeqStack list = Init_SStack();
push_SStack(list, &p1);
push_SStack(list, &p2);
push_SStack(list, &p3);
push_SStack(list, &p4);
struct Postion* p = top_SStack(list);
printf("%s %d\n", p->name, p->age);
printf("--------------------------\n");
}
三,栈的应用(就近匹配)
题目:几乎所有的编译器都具有检测括号是否匹配的能力,那么如何实现编译器中的符号成对检测?如下字符串:
5+5*(6)+9/3*1)-(1+3(
算法思路
从第一个字符开始扫描
当遇见普通字符时忽略,
当遇见左符号时压入栈中
当遇见右符号时从栈中弹出栈顶符号,并进行匹配
匹配成功:继续读入下一个字符
匹配失败:立即停止,并报错
结束:
成功: 所有字符扫描完毕,且栈为空
失败:匹配失败或所有字符扫描完毕但栈非空
实现
int isleft(char* ch)
{
return (ch == '(');
}
int iseigth(char* ch)
{
return (ch == ')');
}
void PrintfError(char* str, char* err, char* ch)
{
printf("错误原理:%s\n", err);
printf("%s\n", str);
int length = ch - str;
int i;
for (i = 0; i < length; i++)
printf(" ");
printf("|");
}
void test()
{
char* str = "5+5*(6)+9/3*1)-(1+3(";
char* poter = str;
SeqStack_2 list = Init_SeqStack();
while (*poter != '\0')
{
if (isleft(*poter))
{
//push栈
Push_SeqStackData(list, *poter);
}
if (iseigth(*poter))
{
//出栈比较
if (isleft(top_SeqStackData(list)))
{
}
else
{
printfError(str, " ", *poter);
}
}
poter++;
}
//判断栈中是否有元素
while (size_SeqStack(list) > 0)
{
printfError(str, "2 ", top_SeqStackData(list));
}
}
int main(int argc, char *argv[])
{
test();
system("pause");
return EXIT_SUCCESS;
}