指针和数据结构

链表

  • 单链表
//一个结点
typedef struct node{
      void*data;
      struct node*next;
      } Node;
 
 //链表,持有头节点、尾结点及当前结点
typedef struct link_list{
      Node* head;
      Node* tail;
      Node* current;
      }LinkedList;

在这里插入图片描述
在使用链表之前要先初始化:

void init_list(LinkedList *list)
{
  list->head=NULL;
  list->tail=NULL;
  list->current=NULL;
 }

在表头添加结点:

void addHead(LinkedList *list,void*data)
{
  Node* node=(Node*)malloc(sizeof(Node));
  node->data=data;  //先创建结点
  
  if(list->head=NULL)
  {
    list->tail=node;
    node->next=NULL;
  }
  else
  {
     node->next=list->head;  //把原本的头结点连接到新结点的后面
  }
   list->head=node;      //更新头结点的值
}

在表尾添加结点:

void addTail(LinkedList *list,void*data)
{
  Node* node=(Node*)malloc(sizeof(Node));
  node->data=data;  
  node->next=NULL;//先创建结点

  if(list->head=NULL)
  {
    list->head=node;
  }
  else
  {
     list->tail->next=node;
  }
     list->tail=node;      //更新头结点的值
 }

返回带有指定数据的结点:

void delete(LinkedList *list,Node *node)
{
   if(node==list->head)  //删除的是表头。
   {
       if(list->head->next==NULL)  
       {
          list->head=list->tail=NULL;
       }else
       {
          list->head=list->head->next;
       }
   }
  else
  {
      Node*tmp=list->head;
      while(tmp!=NULL&&tmp->next!=node)
      {
         tmp=tmp->next;
      }
      if(tmp!=NULL)
      {
          tmp->next=node->next;
      }
  }
  free(node);   //释放结点
}

队列

队列是一种线性数据结构,讲究先进先出,入队操作就是将节点添加到链表头、出列就是从链表尾删除节点。

链表的初始化和之前的一样,节点添加到链表头同上

下面的操作是从链表尾删除节点:

//分为3种情况,空队列,单字节队列,多字节队列
typedef LinkedList   Queue ;

void queuedele(Queue * queue)
{
   Node *tmp=queue->head;
   void *data;
   if(queue->head==NULL)
   {
      data=NULL;
   }
   elseif(queue->head==queue->tail)
   {
     queue->head=queue->tail=NULL;
     data=tmp->data;
     free(tmp);
   }
   else
   {
       while(tmp->next!=queue->tail)
       {
           tmp=tmp->next;
       }
         queue->tail=tmp;
         tmp=tmp->next;
         queue->tail->next=NULL;
         data=tmp->data;
         free(tmp);
    }
   return data;
}

在这里插入图片描述

栈数据结构也是一种链表,行为是先进后出,我们用addHead函数实现入栈,出栈需要增加一个新函数来删除头节点。

typedef LinkedList   Stack;

void *pop(Stack * stack)
{
   Node *node=stack->head;
   if(node==NULL)
   {
      return NULL;
   }
   elseif(node==stack->tail)
   {
     stack->head=stack->tail=NULL;
     void *data=node->data;
     free(node);
     return data;
   }
   else
   {
         stack->head= stack->head->next;
         void *data=node->data;
          free(node);
         return data;
    }
}

树可以有任意数量的子节点,不过,二叉树比较常见,它的每个节点能有0个、1个或是2个子节点。子节点要么是左子节点,要么是右子节点。没有子节点的节点称为叶子节点,就跟树叶一样。

typedef struct tree
{
   struct tree * left;
   struct tree * right;
   void * data;
}TreeNode;

二叉查找树:
插入的新节点后,这个节点的所有左子节点的值都比父节点小,所有右节点的值都比父节点的值大。(左小,右大)

//因为存在改变节点指针所以要传递双重指针
void insertNode(TreeNode **root,COMPARE compare,void *data)
{
//定义申请节点的空间,并且初始化。
  TreeNode *node=(TreeNode *)malloc(sizeof(TreeNode));
  node->data=data;
  node->left=NULL;
  node->right=NULL;
  //判断根节点是否为空,如果为空,就把新节点赋值给根节点
  if(*root==NULL)
  {
     *root==node;
      return;
  }
  while(1)
  {
     if(compare((*root)->data,data)>0)
     {
          if((*root)->left!=NULL)
          {
            *root=(*root)->left;
          }
           else
          {
               (*root)->left=node;
                break;
          }
     }
     else
     {
         if((*root)->right!=NULL)
         {
           *root=(*root)->right;
         }
         else
         {
           (*root)->right=node;
           break;
         }
     }
}

TreeNode *tree=NULL;
insertNode(&tree,(COMPARE) compare,samuel);
insertNode(&tree,(COMPARE) compare,sally);
insertNode(&tree,(COMPARE) compare,susan);       

遍历二叉树
遍历二叉树有三种:前序、中序、后序,它们步骤相同。

  • 访问节点
    处理节点
  • 往左
    转移到左子节点
  • 往右
    转移到右子节点
void inOrder(TreeNode*root,DISPLAY display)
{
   if(root!=NULL)
   {
     inOrder(root->left,display);
     display(root->data);
     inOrder(root->right,display);
}

void postOrder(TreeNode*root,DISPLAY display)
{
   if(root!=NULL)
   {
     postOrder(root->left,display);
     postOrder(root->right,display);
     display(root->data);
}

void preOrder(TreeNode*root,DISPLAY display)
{
   if(root!=NULL)
   {
     display(root->data);
     preOrder(root->left,display);
     preOrder(root->right,display);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值