常用数据结构:链表、红黑树和SPLAY树

FreeBSD自带有这几种数据结构的实现,非常简洁通用。man queue和man tree分别可以看到说明,在sys/queue.h里面实现了单向链表、有尾指针的单向链表、双向链表、有尾指针的双向链表。在sys/tree.h里面实现了红黑树和SPLAY树。不用FreeBSD的可以在这里看到这两个文件的源码: http://fxr.watson.org/fxr/source/sys/tree.h http://fxr.watson.org/fxr/source/sys/queue.h 用法比较简单:

  1 #include <stdio.h>

  2 #include <stdlib.h>

  3 #include <sys/queue.h>

  4 

  5 struct TNode

  6 {

  7         int Value;

  8         SLIST_ENTRY(TNode) Link;

  9 };

 10 

 11 SLIST_HEAD(THead, TNode);

 12 

 13 struct THead Head = SLIST_HEAD_INITIALIZER();

 14 

 15 

 16 int main()

 17 {

 18         int n = 0;

 19         SLIST_INIT(&Head);

 20         do

 21         {

 22                 printf("输入一个数字,非数字结束输入:");

 23                 int Ret = scanf("%d", &n);

 24                 if (Ret > 0 )

 25                 {

 26                         struct TNode *NewNode = (struct TNode*)malloc(sizeof(struct TNode));

 27                         NewNode->Value = n;

 28                         SLIST_INSERT_HEAD(&Head, NewNode, Link);

 29                 }

 30                 else

 31                         break;

 32         }while(1);

 33         printf("你输入的数字列表为:/n");

 34         struct TNode* Node = NULL;

 35         SLIST_FOREACH(Node, &Head, Link)

 36         {

 37                 printf("%d/n", Node->Value);

 38         }

 39         return 0;

 40 }
SLIST_HEAD定义一个头节点类型,类型结构体名是THead, 链表的节点类型是TNode。 比较难理解的是TNode节点里面的SLIST_ENTRY,但看一下源码就知道这个就是用来保存链表指针的结构。 SLIST是单向链表,其他类型的链表用法也差不多。下面看看SPLAY_TREE的例子:
  1 #include <stdio.h>

  2 #include <stdlib.h>

  3 #include <strings.h>

  4 #include <sys/tree.h>

  5 

  6 struct TNode

  7 {

  8         int Key;

  9         int Value;

 10         SPLAY_ENTRY(TNode) Link;

 11 };

 12 

 13 int Comp(struct TNode* Elm1, struct TNode* Elm2)

 14 {

 15         return Elm1->Key - Elm2->Key;

 16 }

 17 

 18 SPLAY_HEAD(THead, TNode) Root = SPLAY_INITIALIZER();

 19 

 20 SPLAY_PROTOTYPE(THead, TNode, Link, Comp);

 21 

 22 SPLAY_GENERATE(THead, TNode, Link, Comp)

 23 

 24 int main()

 25 {

 26         do

 27         {

 28                 printf("input a number:/n");

 29                 int Key;

 30                 if (scanf("%d", &Key) <= 0)

 31                         break;

 32                 printf("input a number:/n");

 33                 int Value;

 34                 if (scanf("%d", &Value) <= 0 )

 35                         break;

 36                 struct TNode* NewNode = (struct TNode*) malloc(sizeof(struct TNode));

 37                 NewNode->Key = Key;

 38                 NewNode->Value = Value;

 39                 if (SPLAY_INSERT(THead, &Root, NewNode) != NULL)

 40                 {

 41                         free(NewNode);

 42                         printf("insert failed!!!/n");

 43                 }

 44                 printf("insert success/n");

 45         }while(1);

 46         if (! SPLAY_EMPTY(&Root) )

 47         {

 48                 do

 49                 {

 50                         int Key = 0;

 51                         printf("input key to find:/n");

 52                         if (scanf("%d", &Key) <= 0)

 53                                 break;

 54                         struct TNode TmpNode;

 55                         bzero(&TmpNode, sizeof(struct TNode));

 56                         TmpNode.Key = Key;

 57                         struct TNode* Node = SPLAY_FIND(THead, &Root, &TmpNode);

 58                         if (! Node )

 59                                 printf("cann't find %d/n", Key);

 60                         else

 61                                 printf("Ok, find it: Key = %d, Value = %d/n", Node->Key, Node->Value);

 62                 }while(1);

 63         }

 64         return 0;

 65 }
代码很简单,就是实现了节点的插入和查询,SPLAY_PROTOTYPE和SPLAY_GENERATE分别是树的操作函数的声明和实现。RB_TREE的用法也类似,不另外写demo了。这些数据结构都是用宏实现的,不是FreeBSD平台的开发环境也可以把这两个头文件拷过去就直接用了。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值