基于链表的多级菜单设计

基于链表的多级菜单设计

前言

最近在做一个简单的界面,需要用到多级菜单,一开始使用的是传统的索引法,在修改时比较乱,在网上有用链表写的,虽然一致都在用c语言,却很少使用链表,于是今天早上便打算用链表制作一个多级菜单,经过一天的努力,终于完成了一个简单的框架,现在只可以添加菜单,而且没有级数限制。 目前只是在gcc下运行成功,还没有在单片机上运行。

主体

传统的双向链表可以寻找上下级的关系,而在多级菜单中还包括同级关系,因此链表的解构应该是树形,包括,父级,子级,同级上和同级下
这里定义一个结构体

typedef struct _menu
{
   
    struct _menu * last;//父极菜单指针
    struct _menu * same_last;//同级菜单下一项指针
    struct _menu * same_next;//同级菜单上一项指针
    char * menu_name;//当前功能名称
    int id;//当前功能号
    void (*funsion)();//功能
    struct _menu*next;//子级菜单
  
}menu_t;

这里,我们还需要几个变量
1.我们需要知道链表当前位置
2.通过按键上下可以在同级之间切换,左右分别表示退出和返回,但是如果我们进入一个界面不想通过上下左右切换链表,所以我们还需要一个全局变量,当这个变量为1时是正常操作,当变量为非1时,我们将获取的按键值交给一个全局变量,故我们需要两个变量

struct {
   
menu_t *now;//当前链表位置
int ctrl;
char input;
}sys_info;

接下来便是创建表头

menu_t*add_funsion(menu_t *head,void * fun,char * str){
       //添加一个功能 head为该界面的第一项,自动在该界面后添加一项功能
	menu_t *p = NULL,*pr = head;  
	p = (menu_t *)malloc(sizeof(menu_t)) ; 
	if(p == NULL){
   		
		printf("NO enough momery to allocate!\n");
		exit(0);
	}
	if(head == NULL){
   		
		head = p;	//head为空,创建头节点	
        printf("创建头节点\n");						
	}else{
   				//如果不是创建头节点	
        int i=1;					                       
		while(pr->same_next!= NULL){
   		//找到同级菜单最后的表
        {
   
            i++;
            pr = pr->same_next;
        }
			
		}
		pr->same_next = p;	//在同级菜单尾部创建一个功能
        p->same_last=pr;
        p->last=head->last;
        p->id=i;
	}
     p->funsion=fun;
	 p->menu_name=str;
	p->same_next = NULL;//下一个同级功能为空
    p->next=NULL;			//下一个子集功能为空
	return head;		
}

上面的函数中如果head是一个空指针,则创建头节点,如果不是空指针,则在其同级最后添加一个结构
然后是在一个目录功能下新建一个目录

menu_t * set_page(menu_t * head,int num)//输入为页的表头
{
   
    for(int i=0;i<num;i++)
    {
   
        if(head->same_next!=NULL)
        head=head->same_next;
        else
        {
   
            printf("超出当前功能号\n");
        }
        
    }
     if(head->next!=NULL)
    head=head->next
  • 23
    点赞
  • 145
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
双向链表多级菜单设计是一种常见的数据结构和算法应用,可以用于实现多级菜单设计。在C语言中,可以通过定义结构体和使用指针来实现双向链表设计。 首先,我们需要定义一个双向链表节点的结构体,包含菜单项的名称、指向上一级菜单的指针、指向下一级菜单的指针以及指向子菜单的指针。例如: ```c typedef struct MenuItem { char name[50]; struct MenuItem* prev; struct MenuItem* next; struct MenuItem* child; } MenuItem; ``` 接下来,我们可以编写一些函数来实现双向链表多级菜单的操作,包括创建菜单项、添加子菜单、添加兄弟菜单等。以下是一个简单的示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> MenuItem* createMenuItem(const char* name) { MenuItem* item = (MenuItem*)malloc(sizeof(MenuItem)); strcpy(item->name, name); item->prev = NULL; item->next = NULL; item->child = NULL; return item; } void addChild(MenuItem* parent, MenuItem* child) { if (parent->child == NULL) { parent->child = child; child->prev = NULL; child->next = NULL; } else { MenuItem* lastChild = parent->child; while (lastChild->next != NULL) { lastChild = lastChild->next; } lastChild->next = child; child->prev = lastChild; child->next = NULL; } } void addSibling(MenuItem* sibling, MenuItem* newSibling) { sibling->next = newSibling; newSibling->prev = sibling; newSibling->next = NULL; } void printMenu(MenuItem* menu) { MenuItem* currentItem = menu; while (currentItem != NULL) { printf("%s\n", currentItem->name); if (currentItem->child != NULL) { printMenu(currentItem->child); } currentItem = currentItem->next; } } int main() { MenuItem* menu = createMenuItem("Menu"); MenuItem* item1 = createMenuItem("Item 1"); MenuItem* item2 = createMenuItem("Item 2"); MenuItem* item3 = createMenuItem("Item 3"); addChild(menu, item1); addChild(menu, item2); addChild(menu, item3); MenuItem* subItem1 = createMenuItem("Sub Item 1"); MenuItem* subItem2 = createMenuItem("Sub Item 2"); addChild(item1, subItem1); addChild(item1, subItem2); MenuItem* siblingItem = createMenuItem("Sibling Item"); addSibling(item3, siblingItem); printMenu(menu); return 0; } ``` 上述代码中,我们首先创建了一个名为"Menu"的菜单项,然后创建了三个子菜单项"Item 1"、"Item 2"和"Item 3",并将它们添加到"Menu"菜单项中。接着,我们创建了两个子菜单项"Sub Item 1"和"Sub Item 2",并将它们添加到"Item 1"菜单项中。最后,我们创建了一个兄弟菜单项"Sibling Item",并将它添加到"Item 3"菜单项后面。 通过调用printMenu函数,我们可以打印出整个菜单的结构。 希望以上内容能够帮助到你!如果有任何问题,请随时提问。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值