<深入理解C指针>学习笔记和总结 第六章 指针和结构体 第二部分

7 篇文章 1 订阅
指针支持数据结构(cap6后一部分,也是数据结构相关)
链表(单)
队列
二叉树




2 代码相关:
准备函数:
typedef struct _employee{
    char name[32];
    unsigned char age;
}Employee;
int compareemployee(Employee *employee1,Employee *employee2)
{
return strcmp(employee1,employee2);
}
void displayemployee(Employee*employee)
{
    printf("%s\t%d\n",employee->name,employee->age);
}
typedef void(*DISPLAY)(void *);
typedef int (*COMPARE)(void *,void *);
单链表:
typedef struct _node{
    void *data;
    struct _node *next;
}Node;
typedef struct _linkedList{
    Node *head;
    Node *tail;
    Node *current;
}LinkedList;
void initializelist(Linkedlist *);
void addhead(Linkedlist* ,void *);
void addtail(Linkedlist *,void *);
void delete(Linkedlist *,Node *);
Node *getnode(Linkedlist *,COMPARE,void *);
void displaylinkedlist(Linkedlist *,DISPLAY);


初始化链表:
void initializelist(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;
}
应用:
Linkedlist linkedlist;
Employee *samuel=(Employee*)malloc(sizeof(Employee));
strcpy(samuel->name,"samuel");
samuel->age=32;
其余俩类似
三个结构体变量初始化
addhead(&linkedlist,samuel);
addhead(&linkedlist,sally);
addhead(&linkedlist,susan);
尾节点:
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;
}
delete:删除节点
delete函数从链表删除一个节点。为了简化这个函数,将删除节点的指针作为要传递的参数。函数的用户有可能有数据的指针,但是没有持有数据的节点的指针。
为了帮助定位节点,我们提供了一个辅助函数getnode来返回节点指针。
Node *getnode(Linkedlist *list,COMPARE compare,void *data)
{
    Node *node =list->head;
    while(node !=NULL)
    {
if(compare(node->data,data)==0)
{
   return node;
}
node=node->next;
    }
    return NULL;
}
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);
    }
}
使用:
Node *node=getnode(&linkedlist,
(int(*)(void *,void *))compareemployee,sally);
delete(&linkedlist,node);


队列:
队列也是一种线性结构。行为类似排队。支持入队与出队。
用链表实现的话,入队操作就是将节点加入到链表头,出队操作就是从链表尾部删除节点。
typedef Linkelist Quene;
void initializequene(Quene* quene)
{
    initializelist(quene);
}
void enquene(Quene *quene,void *node)
{
    addhead(quene,node);
}
删除尾节点(队列)
void *dequene(Quene *quene)
{
    Node *tmp=quene->head;
    void *data;
    if(quene->head==NULL)
    {
data=NULL;
    }else if(quene->head=quene->tail)
    {
quene->head=quene->tail=NULL;
data=tmp->data;
free(tmp);
    }else{
while(tmp->next!=quene->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 initializestrack(Stack *stack)
{
    initializelist(stack);
}
void push(Stack *stack,void *data)
{
    addhead(stack,data);
}
void pop(Stack *stack)
{
    Node *node =stack->head;
    if(node==NULLL)
    {return NULL;}
    else if(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;
    }
}
二叉树:
定义:
typedef strct _tree{
    vpod *data;
    struct _tree *left;
    struct _tree *right;


}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;
}
    }


}
遍历二叉树:
中序:左 中 右
前序:中 左 右
后续:左 右 中


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(....)//前序
{
    if(root!=NULL)
    {
display(root->data);
preorder(root->left,display);
preorder(root->right,display);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值