栈、队列、单链表

栈:

<span style="color:#000000;">#define MAX_SIZE 100//队列的最大长度

//-------------------------栈-----------------------
int top=0;//栈顶变量
void add(char st[],char intput){  //入栈函数
    st[top]=intput;
    top++;
}
void pop(char st[]){  //出栈函数
    top--;
    st[top]='\0';
}
int isEmpty(){  //判断空栈
    if (top==0) {
        return 1;
    }
    return 0;
}
void qing(char st[]){  //清空栈
    while ( top!=0) {
        st[top]='\0';
        top--;
    }
    
}
int main(int argc, const char * argv[]) {
    //数据缓冲区数组,并初始化每一位‘\0’
    char str[20]={'\0'};
    char c=getchar();//接收缓冲字符
    while(c!='\n'){
        if (c=='#') {
            if(!isEmpty()){
               pop(str);//出栈
            }
        }else if(c=='@'){
            qing(str);//清空栈
        }else{
           add(str, c); //入栈
        }
        c=getchar();
    }
    printf("%s\n",str);
    printf("------------------------------\n");
    return 0;
}</span>


队列

<span style="color:#000000;">#include <stdio.h>
int queue[MAX_SIZE] = {};//存放整型数据的队列
int front = -1;//队列头
int rear = -1;//队列尾

/*入队,参数为进入队列的元素*/
void add(int value)
{
    if (rear >= MAX_SIZE-1)
        printf("The queue is full.\n");
    else
    {
        queue[++rear] = value;//在队列尾添加新元素
    }
}

/*出队,返回值为出队列的元素*/
int del()
{
    int temp;
    
    if (front == rear)//队列头等于队列尾代表队列已空
    {
        printf("The queue is empty.\n");
        return -1;
    }
    else
    {
        temp = queue[++front];//取出队列头的元素
        queue[front] = 0;//将队列头元素值设置为0
        return temp;//返回队列头的元素
    }
}

/*显示队列中所有元素*/
void DisplayQueue()
{
    int i = 0;
    for (i = 0; i <= MAX_SIZE; ++i)
    {
        if (queue[i] != 0)//打印队列中不为0的元素,为0代表已经出队
        {
            printf("[%d]", queue[i]);
        }
    }
}</span>



eg.

设编号为1,2,… n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1开始报数,数到m 的那个人出列,它的下一位又从1开始报数,数到m的那个人又出列,依次类推,直到所有人出列为止,由此产生一个出队编号的序列。

#define MAX_SIZE 100//队列的最大长度
int queue[MAX_SIZE] = {};//存放整型数据的队列
int front = -1;//队列头
int rear = -1;//队列尾
/*显示队列中所有元素*/
void DisplayQueue()
{
    int i = 0;
    for (i = 0; i <= MAX_SIZE; ++i)
    {
        if (queue[i] != 0)//打印队列中不为0的元素,为0代表已经出队
        {
            printf("[%d]", queue[i]);
        }
    }
}
/*入队,参数为进入队列的元素*/
void add(int value)
{
    if (rear >= MAX_SIZE-1)
        printf("The queue is full.\n");
    else
    {
        queue[++rear] = value;//在队列尾添加新元素
    }
}

/*出队,返回值为出队列的元素*/
int del()
{
    int temp;
    
    if (front == rear)//队列头等于队列尾代表队列已空
    {
        printf("The queue is empty.\n");
        return -1;
    }
    else
    {
        temp = queue[++front];//取出队列头的元素
        queue[front] = 0;//将队列头元素值设置为0
        return temp;//返回队列头的元素
    }
}
int main(int argc, const char * argv[]) {
    int k,n,m;
    printf("请分别输入k(1<=k<=n),n,m的值,逗号隔开\n");
    scanf("%d,%d,%d",&k,&n,&m);
    printf("------------------------------\n");
    //初始化队列
    for(int i=k;i<=n;i++){
        add(i);
    }
    for (int i=1; i<k; i++) {
        add(i);
    }
   // DisplayQueue();
    int t=0,tp=-1;
    int arr[n];
    while (t<n) {
        for (int i=1; i<=m; i++) {
            if (i==m) {
                arr[t]=del();
                t++;
            }else{
                tp=del();
                add(tp);
            }
        }
    }
    arr[t]=del();//最后一个数
    for (int i=0; i<n; i++) {
        printf("%d\n",arr[i]);
    }
    return 0;
}

单链表

/*建立单链表的函数,形参n为人数*/
Student * creat(int n)
{
    Student *head,*fore,*current;// *head保存表头结点的指针,*fore指向当前结点的前一个结点,*current指向当前结点
    int i;//计数器
    if((head=(Student *)malloc(sizeof(Student)))==NULL)//分配表头空间并检测
    {
        printf("不能分配内存空间!");
        exit(0);
    }
    memset(head->name, '\0', sizeof(head->name));//把表头结点的数据域置空
    head->next=NULL;//把表头结点的链域置空
    fore=head;//fore指向表头结点
    for(i=0;i<n;i++)
    {
        if((current=(Student *)malloc(sizeof(Student)))==NULL)//分配新存储空间并检测
        {
            printf("不能分配内存空间!");
            exit(0);
        }
        fore->next=current;//把current的地址赋给fore所指向的结点的链域,这样就把前一个结点和当前结点连接起来了
        printf("请输入第%d个人的姓名:",i+1);
        scanf("%s",current->name);//在当前结点的数据域中存储姓名
        current->next=NULL;//链表中新建结点的下一个结点为空
        fore=current;//fore指向当前结点,因为下一次循环生成新的结点后当前结点就是前一个结点
    }
    return(head);//返回表头结点的指针
}

/*查找函数,其中head指针是链表的表头指针,
 fullName指针是要查找的人的姓名*/
Student * search(Student *head,char *fullName)
{
    Student *current;//当前指针,指向要与所查找的姓名比较的结点
    char *searchName; //保存查找的结点数据域内姓名的指针
    current=head->next;//从头结点链域指向的结点开始查找
    
    while(current!=NULL)
    {
        /*取出数据域里的姓名与所要查找的姓名比较,
         若相同则返回0,即条件成立*/
        searchName=current->name;
        if(strcmp(searchName,fullName)==0)
        {
            return(current);//返回所要查找结点的地址
        }
        else
        {
            current=current->next;//继续查找下一个结点
        }
    }
    if(current == NULL)
    {
        printf("未找到数据!");
        exit(0);
    }
    return(current);//返回所要查找结点的地址
}

/*另一个查找函数,返回的是上一个查找函数的直接前驱结点的指针,*/
Student * searchForePoint(Student *head,char *fullName)
/*head为表头指针,fullName为指向要查找的姓名的指针
 其实此函数的算法与上面的查找算法是一样的,只是多了一个指针fore,
 并且fore总是指向指针current所指向的结点的直接前驱,
 结果返回fore即是要查找的结点的前一个结点*/
{
    Student *current,*fore;
    char *searchName;
    current=head->next;
    fore=head;
    
    while(current!=NULL)
    {
        searchName=current->name;
        if(strcmp(searchName,fullName)==0)
        {
            return(fore);
        }
        else
        {
            current=current->next;
            fore=fore->next;
        }
    }
    if(fore == NULL)
    {
        printf("未找到数据!");
        exit(0);
    }
    return(fore);//返回所要查找结点的地址
}

/*删除函数,其中delPoint为要删除的结点的指针,
 forePoint为要删除的结点的前一个结点的指针*/
void del(Student *forePoint,Student *delPoint)
{
    Student *s;
    s=delPoint;//指向要删除的结点指针
    forePoint->next=delPoint->next;//将要删除的结点的前一个结点的链域指向要删除的结点的链域
    free(s);//释放要删除的结点指针指向的动态分配的内存空间
}

/*输出链表*/
void printList(Student *head)
{
    Student * p;
    p = head;
    
    if(head != NULL)
    {
        printf("\n链表中数据:\n");
        do {
            printf("[%s]",p->name);
            p = p->next;
        } while (p != NULL);
        printf("\n");
    }
}

/*插入函数,在指针p后插入*/
void insert(Student *p)
{
    char stuName[20];
    Student *s; //指针s是保存新结点地址的
    if((s= (Student *) malloc(sizeof(Student)))==NULL)
    {
        printf("不能分配内存空间!");
        exit(0);
    }
    printf("请输入你要插入的人的姓名:");
    scanf("%s",stuName);
    strcpy(s->name,stuName); //把指针stuName所指向的数组元素拷贝给新结点的数据域
    s->next=p->next; //把新结点的链域指向原来p结点的后继结点
    p->next=s; //p结点的链域指向新结点
}

/*清空链表(释放动态分配的内存)*/
void freeList(Student *head)
{
    Student * p,* q;
    p = head;
    
    if(head != NULL)
    {
        printf("\n开始清空链表中数据。。。\n");
        do {
            q = p;
            p = p->next;
            free(q);
            printf("清空成功!\n");
        } while (p != NULL);
        
    }
}




随堂笔记为个人学习笔记,若有错误,望指出,谢谢!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值