1、顺序表
typedef struct ARRAY //用于管理顺序表的数据类型
{
int * parr;//顺表的起始地址
int len;//表示能够存储的数据节点的个数
int cnt;//已经使用了的表项个数
}ARR,*PARR;
void init_seq_list(PARR p,int length)//初始化一个顺序表
{
p->parr = malloc(sizeof(int)*length);
if(p->parr == NULL)
{
printf("malloc failed!\n");
exit(-1);
}
p->len = length;
p->cnt = 0;
}
bool is_full(PARR p) //判断表满
{
if(p->cnt == p->len)
return true;
else
return false;
}
bool insert_seq_list(PARR p,int pos,int data)//顺序表的插入
{
int i;
if(is_full(p))
return false;
if((pos <1) || (pos > (p->cnt + 1)) )
return false;
for(i = p->cnt -1;i>=pos-1;i--)
{
p->parr[i+1]=p->parr[i];
}
p->parr[pos-1] = data;
p->cnt++;
return true;
}
bool is_empty(PARR p)//判断表空
{
if(p->cnt == 0)
return true;
else
return false;
}
void show_seq_list(PARR p)//顺序表的遍历
{
int i;
if(is_empty(p))
{
printf("没得show\n");
return;
}
for(i=0;i< p->cnt;i++)
printf("%d\t",p->parr[i]);
printf("\n");
}
bool del_seq_list(PARR p,int pos,int *pdata)//顺序表的删除
{
int i;
if(is_empty(p))
{
printf("没得删\n");
return false;
}
if(pos < 1 || pos > p->cnt)
return false;
*pdata = p->parr[pos-1];
for(i=pos;i<p->cnt;i++)
p->parr[i-1]=p->parr[i];
p->cnt--;
return true;
}
2、单链表(循环)
typedef struct node
{
int data;//数据域
struct node *next;
}NODE,*PNODE;
PNODE init_link_list(void)//单链表初始化
{
PNODE phead = malloc(sizeof(NODE));
if(phead == NULL)
{
exit(-1);
//return phead;
}
phead->next = phead;
return phead;
}
PNODE new_node(int dat)
{
PNODE pnew =malloc(sizeof(NODE));
if(pnew == NULL)
return pnew;
pnew->data = dat;
pnew->next = NULL;
return pnew;
}
bool insert_node_tail(PNODE phead,PNODE pnew)// 把地址为pnew的节点插入到单向循环链表的尾部(头节点前面)
{
if(pnew == NULL || phead == NULL)
return false;
PNODE p = phead->next;
while(p->next != phead)
p = p->next;
pnew->next = phead;
p->next = pnew;
return true;
}
bool is_empty(PNODE phead)//判断链表为空,没有满的情况
{
if(phead->next == phead)
return true;
else
return false;
}
void show_list(PNODE phead)//链表的遍历
{
PNODE p = NULL;
if(is_empty(phead))
{
printf("list is empty!\n");
return;
}
p = phead->next;
while(p != phead)//遍历
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
}
bool del_node(PNODE phead,PNODE pdel)//单向循环链表的删除
{
PNODE p;
if(phead == pdel || phead == NULL || pdel == NULL)
return false;
//p = phead->next
p = phead;
while(p->next != phead)
{
if(p->next == pdel )
break;
p = p->next;
//ptmp= ptmp->next;
}
if(p->next != pdel)
return false;
//删除节点
p->next = pdel->next;
pdel->next = NULL;
//free(pdel);
return true;
}
3、双链表
typedef struct node
{
int data;//数据域
struct node *next;
struct node *prev;
}NODE,*PNODE;
PNODE init_dc_list(void)//双向循环链表的初始化
{
PNODE phead = malloc(sizeof(NODE));
if(phead ==NULL)
return phead;
phead->prev = phead;
phead->next = phead;
return phead;
}
PNODE new_node(int dat)//新建一个节点
{
PNODE pnew = malloc(sizeof(NODE));
if(pnew ==NULL)
return pnew;
pnew->data = dat;
pnew->prev = pnew;
pnew->next = pnew;
return pnew;
}
//把地址为pnew的节点插入到双向循环链表的尾部(头节点的前面)
bool list_add_tail(PNODE phead,PNODE pnew)
{
if(pnew == NULL || phead == NULL)
return false;
phead->prev->next = pnew;
pnew->prev = phead->prev;
phead->prev = pnew;
pnew->next = phead;
return true;
}
void show_dc_list(PNODE phead)//双向循环链表的遍历
{
PNODE p;
if(phead == NULL)
return;
p = phead->prev;
while(p != phead)
{
printf("%d\t",p->data);
p = p->prev;
}
printf("\n");
}
//删除双向循环链表中地址为pdel的节点
bool del_dc_node(PNODE phead,PNODE pdel)
{
PNODE p;
if(phead == pdel || phead == NULL || pdel == NULL)
return false;
p = phead->next;
while(p != phead)
{
if(p == pdel )
break;
p = p->next;
}
if(p != pdel)
return false;
pdel->prev->next = pdel->next;
pdel->next->prev = pdel->prev;
pdel->next = pdel->prev = NULL;
return true;
}
PNODE find_node(PNODE phead,int dat)//双向循环链表的查找
{
if(phead == NULL)
return phead;
PNODE p = phead->next;
while(p != phead)
{
if(p->data == dat)
break;
p = p->next;
}
if(p == phead)
{
printf("dat is not in link list\n");
return NULL;
}
return p;
}
4、栈(链栈)
typedef struct node
{
int data;//数据域
struct node *next;
}NODE,*PNODE;
typedef struct stack//管理链式栈的数据类型
{
PNODE pbot;
PNODE ptop;
}ST,*PST;
PST init_link_stack(void)//链栈的初始化
{
PST p = malloc(sizeof(ST));
if(p == NULL)
{
return p;
}
p->ptop = malloc(sizeof(NODE));
if(p->ptop == NULL)
{
free(p);
return NULL;
}
p->pbot = p->ptop ;
p->ptop->next = NULL;
return p;
}
bool push(PST ps,int dat)//入栈
{
PNODE pnew = malloc(sizeof(NODE));
if(pnew == NULL)
return false;
pnew->data = dat;
pnew->next = NULL;
ps->ptop->next = pnew;
ps->ptop = pnew;
return true;
}
bool is_empty(PST ps)//栈空
{
if(ps->ptop == ps->pbot)
return true;
else
return false;
}
bool pop(PST ps,int * pdata)//出栈
{
if(is_empty(ps))
return false;
*pdata = ps->ptop->data;
PNODE p = ps->pbot;
while(p->next != ps->ptop )
{
p = p->next;
}
ps->ptop = p;
free(p->next);
ps->ptop->next = NULL;
return true;
}
void show_stack(PST ps)//栈的遍历
{
PNODE p = NULL;
if(is_empty(ps))
{
printf("stack is empty!\n");
return;
}
PNODE ptmp = ps->ptop;
while(ptmp != ps->pbot)
{
PNODE p = ps->pbot;
while(p->next != ptmp )
{
p = p->next;
}
printf("%d\t",ptmp->data);
ptmp = p;
}
printf("\n");
}
5、队列(循环队列)
typedef struct queue //用于管理循环队列的数据类型
{
int * pq;//循环队列的起始地址
int f;//队头下标
int r;//队尾下标
}QUE,*PQUE;
PQUE init_queue(void)//初始化空的循环队列,大小为size(节点的个数)
{
PQUE p = malloc(sizeof(QUE));
if(p == NULL)
return p;
p->pq = malloc(SIZE * sizeof(int));
if(p->pq == NULL)
{
free(p);
return NULL;
}
p->f = p->r = 0;
return p;
}
bool is_full(PQUE p)//队列满
{
if( p->f == ((p->r + 1) % SIZE) )
return true;
else
return false;
}
bool en_queue(PQUE p,int dat)//把dat入队(队尾)
{
if(p == NULL)
return false;
if(is_full(p))
return false;
p->pq[p->r] = dat;
p->r = (p->r + 1)%SIZE;
return true;
}
bool is_empty(PQUE p)//队列空
{
if(p->f == p->r)
return true;
else
return false;
}
bool out_queue(PQUE p,int * pdata)//出队
{
if(p == NULL)
return false;
if(is_empty(p))
return false;
*pdata = p->pq[p->f];
p->f = (p->f + 1)%SIZE;
return true;
}
bool show_queue(PQUE p)//队的遍历
{
if(is_empty(p))
{
printf("没得show\n");
return false;
}
int i = p->f;
while(i != p->r)
{
printf("%d\t",p->pq[i]);
i = (i+1)%SIZE;
}
printf("\n");
return true;
}
6、内核链表
节点设计
struct stu
{
int age;
。。。
struct list_head mbr;
};
其中
struct list_head {
struct list_head *next, *prev;
};
内核链表操作常用的函数或宏
初始化内核链表
INIT_LIST_HEAD(ptr) //ptr为小结构体指针struct list_head *
插入节点 //把地址为new的小结构体,插入到头节点的后面(首部)
static inline void list_add(struct list_head *new, struct list_head *head)
//把地址为new的小结构体,插入到头结点的前面(尾部)
static inline void list_add_tail(struct list_head *new, struct list_head *head)
删除/移动节点
//删除地址为entry的内核链表节点
static inline void list_del(struct list_head *entry)
//把地址为list的节点移动到头结点的后面
static inline void list_move(struct list_head *list,struct list_head *head)
//把地址为list的节点移动到头节点的前面(尾部)
static inline void list_move_tail(struct list_head *list,struct list_head *head)
判断链表是否为空
static inline int list_empty(struct list_head *head)
由小结构体的地址ptr,获得大结构体的地址
//ptr 为小结构体地址struct list_head * ,type为大结构体类型,member为小结构体在大结构体中的变量名
list_entry(ptr, type, member)
遍历
//向后遍历,pos为循环控制变量,pos类型为struct list_head * ,head为内核链表头结点的地址,类型struct list_head *
#define list_for_each(pos, head) for(pos = (head)->next; pos != (head); pos = pos->next)
//向前遍历
#define list_for_each_prev(pos, head) for(pos = (head)->prev; pos != (head); pos = pos->prev)
//向后遍历的安全版,用于删除节点的场合,n为中间变量,类型为struct list_head *
list_for_each_safe(pos, n, head)
通过大结构体指针向后遍历,pos为循环控制变量,大结构体指针,pos类型为struct xxx *
//head内核链表头结点地址,类型为小结构体指针struct list_head*
//member为小结构体在大结构体中的变量名
list_for_each_entry(pos, head, member)
//通过大结构体指针向后遍历的安全版,用于删除节点的场合
//n是中间变量,类型为大结构体指针struct xxx *
list_for_each_entry_safe(pos, n, head, member)
struct stu
{
int age;
struct list_head mbr;
};
//创建一个空的内核链表,返回大结构的地址
struct stu * create_klist(void)
{
struct stu * phead = malloc(sizeof(struct stu));
if(phead == NULL)
return phead;
INIT_LIST_HEAD(&(phead->mbr));
return phead;
}
//构造一个新节点,返回大结构体的地址
struct stu * new_node(int data)
{
struct stu * pnew = malloc(sizeof(struct stu));
if(pnew == NULL)
return pnew;
pnew->age = data;
INIT_LIST_HEAD(&(pnew->mbr));
return pnew;
}
bool insert_knode_tail(struct stu* phead,struct stu* pnew)//插入一个节点
{
if(phead == NULL || pnew == NULL)
return false;
list_add_tail(&(pnew->mbr), &(phead->mbr));
return true;
}
void show_klist(struct stu* phead)//遍历内核链表
{
struct stu * p;
struct list_head * pos;
list_for_each(pos, &(phead->mbr))
{
p=list_entry(pos, struct stu, mbr);
printf("%d\t",p->age);
}
printf("\n");
}
bool del_knode(struct stu *phead,int data)//删除节点
{
if(phead == NULL)
return false;
struct stu * pos,*n;
list_for_each_entry_safe(pos, n, &(phead->mbr), mbr)
{
if(pos->age == data)
break;
}
if(pos == phead)
return false;
list_del(&(pos->mbr));
return true;
}
7、二叉树(先序遍历)
二叉树的遍历
先序遍历:先访问根节点,然后先序遍历左子树,最后先序遍历右子树
中序遍历:先中序遍历左子树,再访问根节点,最后中序遍历右子树
后序遍历:先后序遍历左子树,然后后序遍历右子树,最后访问根节点
typedef struct node
{
char data;//数据域
struct node *plch;//左指针
struct node *prch;//右指针
}NODE,*PNODE;
PNODE init_btree(void)//初始化二叉树
{
PNODE pa,pb,pc,pd,pe,pf;
pa = malloc(sizeof(NODE));
pb = malloc(sizeof(NODE));
pc = malloc(sizeof(NODE));
pd = malloc(sizeof(NODE));
pe = malloc(sizeof(NODE));
pf = malloc(sizeof(NODE));
pa->plch = pb;
pa->prch = pc;
pb->plch = pd;
pb->prch = pe;
pc->plch = pf;
pc->prch = NULL;
pd->plch = NULL;
pd->prch = NULL;
pe->plch = NULL;
pe->prch = NULL;
pf->plch = NULL;
pf->prch = NULL;
pa->data = 'a';
pb->data = 'b';
pc->data = 'c';
pd->data = 'd';
pe->data = 'e';
pf->data = 'f';
return pa;
}
void pre_show(PNODE proot)//递归遍历二叉树
{
if(proot != NULL)
{
printf("%c\t",proot->data);//先访问根节点
if(proot->plch != NULL)
pre_show(proot->plch);//先序遍历左子树
if(proot->prch != NULL)
pre_show(proot->prch);//先序遍历右子树
}
}