目录
01 单链表
引言
本人所读专业为自动化,课程体系中没有《数据结构》。但在学习C语言、C51单片机之后,对程序有了一定的兴趣,于是便买了一本《数据结构》。我们专业《数据结构》虽然没有开设,但是《数据结构》对学习单片机,写程序算法的帮助是显而易见的。
根据《数据结构》第二章单链表内容所写代码如下
参考书籍:《数据结构C语言版》第二版
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR 0
#define OK 1
/* 单链表 */
typedef int Status;
typedef struct student
{
char num[12];
char name[10];
int score;
}ElemType;
//链表结构体
typedef struct LNode
{
ElemType data; //结点的数据域
struct LNode *next; //结点的指针域
}LNode,*LinkList; //LinkList为指向结构体Lnode的指针类型
//初始化链表
Status InitList(LinkList *L)
{
(*L)=(LinkList)malloc(sizeof(LNode));
(*L)->next = NULL;
return OK;
}
//判断是否为空链表
int ListEmpty(LinkList L)
{
if(L->next)
return ERROR;
else
return OK;
}
//销毁链表
int ListDestroyed(LinkList *L)
{
if (!(*L))
return ERROR;
LNode *p;
while(*L)
{
p=*L;
(*L)=(*L)->next;
free(p);
}
return OK;
}
//清空链表
int ClearList(LinkList *L)
{
LNode *p,*q;
p=(*L)->next;
while(p)
{
q=p->next;
free(p);
p=q;
}
(*L)->next=NULL;
return OK;
}
//求链表长度
int LenList(LinkList *L)
{
LNode *p;
int i=0;
p=(*L)->next;
while(p)
{
i++;
p=p->next;
}
return i;
}
//取值
Status GetElem(LinkList L,int n,ElemType *e)
{
LNode *p;int i=1;
p=L->next;
if(!p || i>n)return ERROR;
while(p&&i<n)
{
p=p->next;
i++;
}
*e=p->data;
return OK;
}
//比较
int Compare(ElemType *e1,ElemType *e2)
{
if(e1->name==e2->name && e1->num==e2->num && e1->score==e2->score)
return 1;
else
return 0;
}
//查找
LNode* LocateElem(LinkList L,ElemType e)
{
LNode *p=L->next;
while (p && Compare(&L->data,&e)!=1)
{
p = p->next;
}
if(!p)return NULL;
return p;
}
//插入
Status ListInsert(LinkList *L,int n,ElemType e)
{
LNode *p=*L;
int i=0;
while(p&&(i<n-1))
{
p=p->next;
i++;
}
if(!p || i>n-1)return ERROR;
LNode *s;
s=(LinkList)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
//删除
Status ListDelete(LinkList *L,int n)
{
LNode *p=*L;
int i=0;
while(p->next && (i<n-1))
{
p=p->next;
i++;
}
if(!(p->next) || i>n-1)return ERROR;
LNode *q;
q=p->next;
p->next=q->next;
free(q);
return OK;
}
/* 创建单链表 */
void CreateList_H(LinkList *L,int n)//前插法
{
(*L)=(LinkList)malloc(sizeof(LNode));
(*L)->next=NULL;
int i=0;
for(i=0;i<n;i++)
{
LNode *p;
p=(LinkList)malloc(sizeof(LNode));
scanf("%s%s%d",&p->data.num,&p->data.name,&p->data.score);
p->next=(*L)->next;
(*L)->next=p;
}
}
void CreateList_R(LinkList *L,int n)//后插法
{
(*L)=(LinkList)malloc(sizeof(LNode));
(*L)->next=NULL;
LNode *r=*L;
int i=0;
for(i=0;i<n;i++)
{
LNode *p;
p=(LinkList)malloc(sizeof(LNode));
scanf("%s%s%d",&p->data.num,&p->data.name,&p->data.score);
p->next=NULL;r->next=p;
r=p;
}
}
int main()
{
LinkList L,L1;
ElemType student1;
InitList(&L);
InitList(&L1);
ElemType student2={"2021","LIUBIN",100};
ListInsert(&L,1,student2) ;
GetElem(L,1,&student1);
printf("插入内容:%s %s %d\n",student1.num,student1.name,student1.score);
ListInsert(&L,1,student2) ;
ListInsert(&L,1,student2) ;
ListInsert(&L,1,student2) ;
ListInsert(&L,1,student2) ;
ListDelete(&L,1);
ListDelete(&L,1);
CreateList_H(&L1,1);
GetElem(L1,1,&student1);
printf("插入内容:%s %s %d\n",student1.num,student1.name,student1.score);
printf("单链表长度:%d",LenList(&L1));
}
效果如图1
图1
STM32项目
将单链表用在STM32中构建多级菜单
部分代码:
/*主菜单画面*/
MenuItem mainMenuItem[]={
{"Setting", &SettingMenu},//下级菜单指针
{"Option 2",NULL},
{"Option 3",NULL},
{"Option 4",NULL},
{"Option 5",NULL},
{"Test1", NULL},
{"Test2", NULL}
};
MenuData mainMenu_data={20,12,SIZE(mainMenuItem),76};//主菜单参数
Menu MainMenu={mainMenuItem,&mainMenu_data,(*DrawMainMenu)};
Menu* currentMenu=&MainMenu;//菜单指针->指向当前菜单
/*设置菜单界面*/
MenuItem SettingMenuItem[]={
{"UI Speed",&UISpeedMenu},
{"Test1", NULL},
{"Test2", NULL},
{"Test3", NULL},
{"INFO", &INFOMenu},
{"Return", &MainMenu},
};
MenuData SettingMenuIData={20,12,SIZE(SettingMenuItem),76};
Menu SettingMenu={SettingMenuItem,&SettingMenuIData,(*DrawSettingMenu)};
/*UISpeed设置界面*/
MenuItem UISpeedItem[]={
{"UI Speed",&SettingMenu},
};
MenuData UISpeedData={20,12,SIZE(UISpeedItem),76};
Menu UISpeedMenu={UISpeedItem,&UISpeedData,(*DrawSetUISpeed)};
/*INFO*/
MenuItem INFOItem[]={
{"InFo",&SettingMenu},
};
MenuData INFOData={20,12,SIZE(INFOItem),76};
Menu INFOMenu={INFOItem,&INFOData,(*DrawINFO)};
void SelectMenu(Menu *menu) //菜单指针->指向下一级指针 由按键触发
{
if(menu->Item[UI.select].next!=NULL)
{
currentMenu=menu->Item[UI.select].next;
if(menu->select!=NULL)
{
SelectFunction();
}
Menu_Init();
}
}
void SelectFunction() //函数指针->指向当前菜单对应的动画函数
{
select=currentMenu->select;
}
演示UI速度更改
实际效果:(项目未完成,但大体框架已经搭好,等PCB打样)
9月17日