vlambda博客
学习文章列表

C语言实现个循环静态链表

C语言实现个循环静态链表

    平时用循环缓冲区接收数据习惯了,突然有个需求不让用了。因为在数据缓冲的时间段内可能会删除数据,而且还要实现按照接收的顺序存储,相信小伙伴们也都遇到过同样的需求,下面来个简单的循环链表模型,希望能帮上有需要的。废话不多说,直接上代码。



/*

功能:建立一个静态循环链表

限制:数组长度不大于(0xffffU-1)且第0个位置不能存储有效数据,用于存放有效数据个数

*/

 

/*头文件*/

#include<stdio.h>

#include<stdint.h>

 

/*宏定义*/

#define N_SIZE        7U

#defineUSED_SEAT     1U

#defineLAST_DATA     0xffffU

 

/*结点结构体*/

typedef structnode

{

    int flag;

    int next;

    int data;

}node_t;

 

/*声明内部函数*/

static intFindNodeSeat(node_t *arry, int seat);

static intFindNodeData(node_t *arry, int key);

static intMallocNode(node_t *arry);

 

/*找到下标为src的结点,返回找到的前向下标值,如果没有找到,返回0*/

static intFindNodeSeat(node_t *arry, int seat)

{

    int i = 0;

    int ret = 0;/*查找结果*/

    int temp = 0;/*记录前向结点的下标*/

 

    i = arry[0].next;/*从第1个有效结点开始找*/

 

    if(arry[0].flag == USED_SEAT)/*已经被使用的结点*/

    {

          while(i != 0)/*有后继结点*/

          {

                if(i == seat)

                {

                      /*找到了要查找的结点位置*/

                      ret = 1;

                      break;

                }

                else

                {

                      temp = i;/*记录前向结点的下标*/

                      i = arry[i].next;

                      if(i == LAST_DATA)

                      {

                            /*到链表的最后一个结点了*/

                            ret = 2;

                            break;

                      }

                      else

                      {

                            ret = 0;

                      }

                }

          }

    }

    else

    {

          printf("空链表,查找结点失败\n");

    }

   

    if(ret == 1)

    {

          /*找到要查找的结点*/

          i = temp;

    }

    else

    {

          i = 0;

          printf("没有找到要查找的结点\n");

    }

 

    return i;

}

 

/*找到数据内容为key的结点,返回找到的前向下标值,如果没有找到,返回0*/

static intFindNodeData(node_t *arry, int key)

{

    int i = 0;

    int ret = 0;/*查找的结果*/

    int temp = 0;/*记录前向结点的下标*/

 

    i = arry[0].next;/*从第1个有效结点开始找*/

 

    if(arry[0].flag == USED_SEAT)/*已经被使用的结点*/

    {

          while(i != 0)/*有后继结点*/

          {

                if(arry[i].data == key)

                {

                      /*找到了要查找的结点位置*/

                      ret = 1;

                      break;

                }

                else

                {

                      temp = i;/*记录前向结点的下标*/

                      i = arry[i].next;

                      if(i == LAST_DATA)

                      {

                            /*到链表的最后一个结点了*/

                           printf("到链表的最后一个结点了\n", i);

                            temp = i;

                            ret = 2;

                            break;

                      }

                      else

                      {

                            ret = 0;

                      }

                }

          }

    }

    else

    {

          printf("空链表,查找结点失败\n");

    }

   

    if(ret == 1)

    {

          /*找到要查找的结点*/

          i = temp;

    }

    else

    {

          i = 0;

          printf("没有找到要查找的结点\n");

    }

 

    return i;

}

 

/*初始化缓冲区*/

voidInitList(node_t *arry)

{

    int i=0;

 

    for(i=0; i<N_SIZE; i++)

    {

          arry[i].flag = 0;/*0:空,1:占用*/

          arry[i].next = 0;/*0:没有后继结点,0xffff:表示最后一个有效结点*/

          arry[i].data = 0;/*数据内容*/

    }

}

 

/*分配一个空结点,如果找到空结点返回结点值,如果没有找到空结点,返回缓冲区的大小*/

static intMallocNode(node_t *arry)

{

    int i = 0;

   

    for(i=0; i<N_SIZE; i++)

    {

          if(arry[i].flag == 0)

          {

                /*找到一个可用结点*/

                if(i == 0)

                {

                      /*i=0表示尾空表*/

                      arry[0].flag = USED_SEAT;/*0:空,1:占用*/

                      arry[0].next = 1U;/*0:没有后继结点*/

                      arry[0].data +=1U;/*arry[0].data用于存放有效数据个数,有效数据个数加1*/

                      i = 1;/*0个位置保留*/

                }

                else

                {

                      /*不动作*/

                }

 

                break;/*找到一个可用结点就退出*/

          }

          else

          {

                /*不动作*/

          }

    }

 

    return i;

}

 

/*在尾部插入一个结点*/

intInsertTail(node_t *arry, int key)

{

    int i = 0;

    int j = 0;

   

    i = MallocNode(arry);

 

    if(i == 1)

    {

          arry[i].flag = USED_SEAT;/*0:空,1:占用*/

          arry[i].next = LAST_DATA;/*LAST_DATA:最后一个有效结点*/

          arry[i].data = key;/*数据内容*/

    }

    else if(i == N_SIZE)

    {

          /*缓冲区已满,需要调头*/

          i = arry[0].next;

         

          printf("已满 head = %d\n", i);

          /*找到上一个被占用且游标为LAST_DATA的结点,将找到的结点的next指向i*/

          for(j=1; j<N_SIZE; j++)

          {

                if(arry[j].next == LAST_DATA)

                {

                      /*找到了最后一个结点*/

                      arry[j].next = i;

                      arry[i].flag =USED_SEAT;/*0:空,1:占用*/

                      arry[i].data = key;/*数据内容*/

                      arry[0].next =arry[i].next;/*修改第一个元素的位置*/

                      arry[i].next =LAST_DATA;/*LAST_DATA:最后一个有效结点*/

                     

                      break;

                }

                else

                {

                      /*不动作*/

                }

          }

    }

    else if(i < N_SIZE)

    {

          /*找到上一个被占用且游标为LAST_DATA的结点,将找到的结点的next指向i*/

          for(j=1; j<N_SIZE; j++)

          {

                if(arry[j].next == LAST_DATA)

                {

                      break;

                }

          }

 

          if(j < N_SIZE)

          {

                /*找到了上一个结点*/

                arry[j].next = i;

                arry[i].flag = USED_SEAT;/*0:空,1:占用*/

                arry[i].next = LAST_DATA;/*LAST_DATA:最后一个有效结点*/

                arry[i].data = key;/*数据内容*/

                arry[0].data += 1U;/*有效数据个数加1*/

          }

          else

          {

                /*error:没找到上一个结点*/

          }

    }

    else

    {

          /*error:没找到上一个结点*/

    }   

 

    return i;

}

 

/*删除下标为seat的结点*/

intDeletSeatNode(node_t *arry, int seat)

{

    int i = 0;

    int temp = 0;/*记录前向结点的下标*/

 

    temp = FindNodeSeat(arry, seat);

    i = arry[temp].next;

    if(i != 0)

    {

          /*找到要删除的元素*/

          /*将其前向结点的next改为该结点的next,删除该结点,总数减1*/

          arry[temp].next = arry[i].next;

          arry[i].flag = 0;

          arry[i].next = 0;

          arry[i].data = 0;

 

          /*如果只剩下1个有效值了,初始化缓冲区*/

          if(arry[0].data == 1)

          {

                arry[0].flag = 0;

                arry[0].next = 0;

                arry[0].data = 0;

          }

          else if(arry[0].data > 0)

          {

                arry[0].data -= 1;

          }

          else

          {

                /*不动作*/

          }

    }

    else

    {

          printf("没有找到要删除的结点\n");

    }

 

    return i;

}

 

/*删除数据内容为key的结点*/

intDeletDataNode(node_t *arry, int key)

{

    int i = 0;

    int temp = 0;/*记录前向结点的下标*/

 

    temp = FindNodeData(arry, key);

    i = arry[temp].next;

    if(i != 0)

    {

          /*找到要删除的元素*/

          /*将其前向结点的next改为该结点的next,删除该结点,总数减1*/

          arry[temp].next = arry[i].next;

          arry[i].flag = 0;

          arry[i].next = 0;

          arry[i].data = 0;

 

          /*如果只剩下1个有效值了,初始化缓冲区*/

          if(arry[0].data == 1)

          {

                arry[0].flag = 0;

                arry[0].next = 0;

                arry[0].data = 0;

          }

          else if(arry[0].data > 0)

          {

                arry[0].data -= 1;

          }

          else

          {

                /*不动作*/

          }

    }

    else

    {

          printf("没有找到要删除的结点\n");

    }

 

    return i;

}

 

/*找到数据内容为src的结点,并将数据内容放到des,返回找到的下标值,如果没有找到,返回0*/

intFindDataNode(node_t *arry, int src, int *des)

{

    int i = 0;

    int temp = 0;/*记录前向结点的下标*/

 

    temp = FindNodeData(arry, src);

    i = arry[temp].next;

    if(i != 0)

    {

          /*找到要查找的元素*/

          printf("找到要查找的元素 i = %d\n", i);

          *des = arry[i].data;

    }

    else

    {

          i = 0;/*没有找到返回0*/

          printf("没有找到要查找的结点\n");

    }

 

    return i;

}

 

/*找到数据内容为src的结点,并用des数据内容替换该元素的值,返回找到的下标值,如果没有找到,返回0*/

intPlaceNode(node_t *arry, int src, int des)

{

    int i = 0;

    int temp = 0;/*记录前向结点的下标*/

 

    temp = FindNodeData(arry, src);

    i = arry[temp].next;

    if(i != 0)

    {

          /*找到要查找的元素*/

          printf("找到要替换的元素 i = %d\n", i);

          arry[i].data = des;

    }

    else

    {

          i = 0;/*没有找到返回0*/

          printf("没有找到要替换的结点\n");

    }

 

    return i;

}

 

/*遍历链表*/

voidListScan(node_t *arry)

{

    int i = 0;

 

    if(arry[0].flag == USED_SEAT)

    {

          while(arry[i].next != 0)/*有后继结点*/

          {

                if(arry[i].next == LAST_DATA)

                {

                      /*到链表的最后一个结点了*/

                      printf("(%d, %d, %d,%d)", i, arry[i].flag, arry[i].data, arry[i].next);

                      break;

                }

                else

                {

                      printf("(%d, %d, %d,%d)", i, arry[i].flag, arry[i].data, arry[i].next);

                      i = arry[i].next;

                }

          }

    }

    else

    {

          printf("空链表\n");

    }

    printf("\n");

}

 

/*主函数*/

void main(void)

{

    int i = 0;

    int n_data = 5;

    int test = 0;

    int find = 0;

   

    node_t ListBuf[N_SIZE];/*数据缓冲区*/

 

    /*初始化缓冲区*/

    printf("初始化缓冲区\n");

    InitList(ListBuf);

    ListScan(ListBuf);

 

    /*插入数据*/

    printf("插入数据\n");

    for(i=0; i<(N_SIZE-1); i++)

    {

          InsertTail(ListBuf, i);

          ListScan(ListBuf);

    }

 

    /*按照数据内容删除数据*/

    printf("按照数据内容删除数据\n");

    for(i=1; i<N_SIZE; i++)

    {

          DeletDataNode(ListBuf, (i-1));

          ListScan(ListBuf);

    }

 

    /*插入数据*/

    printf("插入数据\n");

    for(i=0; i<(N_SIZE-1); i++)

    {

          InsertTail(ListBuf, i);

          ListScan(ListBuf);

    }

 

    /*按照下标内容删除数据*/

    printf("按照下标删除数据\n");

    for(i=1; i<N_SIZE; i++)

    {

          DeletSeatNode(ListBuf,i);

          ListScan(ListBuf);

    }

 

    /*删除一个不存在的结点*/

    printf("删除一个不存在的结点\n");

    DeletSeatNode(ListBuf,0);

    ListScan(ListBuf);

 

    /*插入数据*/

    printf("插入数据\n");

    for(i=0; i<(N_SIZE-1); i++)

    {

          InsertTail(ListBuf, i);

          ListScan(ListBuf);

    }

    /*循环覆盖老数据*/

    printf("循环覆盖老数据\n");

    for(i=0; i<(N_SIZE-1); i++)

    {

          InsertTail(ListBuf, (i+N_SIZE));

          ListScan(ListBuf);

    }

 

    /*查找数据*/

    find = 9;

    printf("查找数据%d\n", find);

    FindDataNode(ListBuf, find, &test);

    printf("test = %d\n", test);

 

    /*替换数据*/

    find = 10;

    printf("替换数据%d\n", find);

    test = 123;

    PlaceNode(ListBuf, find, test);

    ListScan(ListBuf);

 

    /*删除指定位置数据*/

    find = 3;

    printf("删除指定位置数据 %d\n", find);

    DeletSeatNode(ListBuf, find);

    ListScan(ListBuf);

 

    /*删除指定内容数据*/

    find = 11;

    printf("删除指定内容数据 %d\n", find);

    DeletDataNode(ListBuf, find);

    ListScan(ListBuf);

}


    花了大半天的时间基本功能和框架有了,纯属娱乐,大神勿喷。