指针支持数据结构(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);
}
}
链表(单)
队列
二叉树
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);
}
}