单向链表
#ifndef _LINK_H_
#define _LINK_H_
typedef int Datatype;
#include<head.h>
typedef struct node
{
Datatype data;
struct node *pnext;
}Link_Node_t;
typedef struct link
{
Link_Node_t *phead;
int clen;
}Link_t;
extern Link_t *create_link();
extern int push_link_head(Link_t *plink,Datatype data);
extern int print_list(Link_t *plink);
extern int push_tail(Link_t *plink,Datatype data);
extern int pop_link_head(Link_t *plink) ;
extern int is_empty_list(Link_t *plink);
extern int pop_link_tail(Link_t *plink);
extern Link_Node_t * find_list_element(Link_t *plink,Datatype date);
extern void updata_list_element(Link_t *plink,Link_Node_t *q,Datatype date);
extern void delete_list(Link_t *plink);
extern Link_Node_t * find_midlist(Link_t *plink);
extern Link_Node_t * find_last_num(Link_t *plink,int num);
extern void delete_list_element(Link_t *plink,int date);
extern Link_Node_t * find_last_num_fa(Link_t *plink,int num);
extern void invert_list_element(Link_t *plink);
extern void insert_list_element(Link_t *plink);
#endif
#include"link.h"
Link_t *create_link()
{
Link_t *plink = malloc(sizeof(Link_t));
if(NULL == plink)
{
perror("fail to malloc\n");
return NULL ;
}
plink->phead = NULL;
plink->clen = 0;
return plink;
}
//头插
int push_link_head(Link_t *plink,Datatype data)
{
Link_Node_t *pnode = malloc(sizeof(Link_Node_t));
if(NULL == pnode)
{
perror("fail malloc");
return -1;
}
pnode->data = data;
pnode->pnext = NULL;
pnode->pnext = plink->phead;
plink->phead = pnode;
plink->clen++;
return 0;
}
//遍历
int print_list(Link_t *plink)
{
Link_Node_t *p;
p = plink->phead;
while(p != NULL)
{
printf("data = %d\n",p->data);
p = p->pnext;
}
return 0;
}
//尾插
int push_tail(Link_t *plink,Datatype data)
{
Link_Node_t *pnode = malloc(sizeof(Link_Node_t));
if(NULL == pnode)
{
perror("fail malloc");
return -1;
}
pnode->data = data;
pnode->pnext = NULL;
if(plink->phead == NULL)
{
push_link_head(plink,1);
}
Link_Node_t *p;
p = plink->phead;
while(p->pnext != NULL)
{
p = p->pnext;
}
p->pnext = pnode;
plink->clen++;
return 0;
}
//头删
int pop_link_head(Link_t *plink)
{
if(is_empty_list(plink))
{
return 0;
}
Link_Node_t *p = plink->phead;
plink->phead = p->pnext;
free(p);
plink->clen--;
return 0;
}
//判空
int is_empty_list(Link_t *plink)
{
if(plink->phead == NULL)
{
return 1;
}
else
{
return 0;
}
}
//尾删
int pop_link_tail(Link_t *plink)
{
if(is_empty_list(plink))
{
return -1;
}
else if(plink->clen == 1)
{
pop_link_head(plink);
}
else
{
Link_Node_t *p = plink->phead;
while(p->pnext->pnext != NULL)
{
p = p->pnext;
}
free(p->pnext);
p->pnext = NULL;
plink->clen--;
}
return 0;
}
//找指定节点
Link_Node_t * find_list_element(Link_t *plink,Datatype date)
{
Link_Node_t *p = plink->phead;
while(p->data != date)
{
p = p->pnext;
}
return p;
}
//改指定节点
void updata_list_element(Link_t *plink,Link_Node_t *q,Datatype date)
{
Link_Node_t *p = plink->phead;
p = q;
p->data = date;
}
//删除链表
void delete_list(Link_t *plink)
{
int ret = 0;
while(pop_link_tail(plink) == 0)
{
}
/*
while(plink->phead != NULL)
{
pop_link_tail(plink);
}*/
free(plink);
}
//找中间节点
Link_Node_t * find_midlist(Link_t *plink)
{
Link_Node_t *p = plink->phead;
int i = plink->clen / 2;
while(i)
{
p = p->pnext;
--i;
}
return p;
}
//快慢指针法--找中间节点
//Link_Node_t * find_midlist_fs(Link_t *plink)
//{
//}
//找指定倒数第几节点
Link_Node_t * find_last_num(Link_t *plink,int num)
{
Link_Node_t *p = plink->phead;
int i = plink->clen;
i = i + 1 - num;
if(i <= 0)
{
printf("链表只有%d个节点\n",plink->clen);
return NULL;
}
else
{
while(i - 1)
{
p = p->pnext;
--i;
}
return p;
}
}
//快慢指针法--找倒数节点
Link_Node_t * find_last_num_fa(Link_t *plink,int num)
{
Link_Node_t *pfast = plink->phead;
Link_Node_t *pslow = plink->phead;
while(pfast->pnext != NULL)
{
if(num - 1 <= 0)
{
break;
}
num--;
pfast = pfast->pnext;
}
while(pfast->pnext != NULL)
{
pfast = pfast->pnext;
pslow = pslow->pnext;
}
return pslow;
}
//删除指定节点
void delete_list_element(Link_t *plink,int date)
{
Link_Node_t *p = plink->phead;
if(date == 8)
{
pop_link_head(plink);
}
else
{
while(p->pnext->data != date)
{
p = p->pnext;
}
Link_Node_t *q = plink->phead;
q = p->pnext->pnext;
free(p->pnext);
p->pnext = q;
plink->clen--;
}
}
//链表倒置
void invert_list_element(Link_t *plink)
{
Link_Node_t * ptemp = plink->phead;
Link_Node_t * pinsert = plink->phead;
plink->phead = NULL;
while(ptemp != NULL)
{
ptemp = ptemp->pnext;
pinsert->pnext = plink->phead;
plink->phead = pinsert;
pinsert = ptemp;
}
}
//链表排序
void insert_list_element(Link_t *plink)
{
Link_Node_t * ptemp = plink->phead->pnext;
Link_Node_t *pinsert = NULL;
Link_Node_t *p = NULL;
plink->phead->pnext = NULL;
while(ptemp != NULL)
{
pinsert = ptemp;
ptemp = ptemp->pnext;
if(pinsert->data < plink->phead->data)
{
pinsert->pnext = plink->phead;
plink->phead = pinsert;
}
else
{
p = plink->phead;
while(p->pnext != NULL && p->pnext->data < pinsert->data)
{
p = p->pnext;
}
pinsert->pnext = p->pnext;
p->pnext = pinsert;
}
}
}
#include"link.h"
int main(int argc, const char *argv[])
{
Link_t *plink = create_link();
if (NULL == plink)
{
return -1;
}
push_link_head(plink, 1);
push_link_head(plink, 9);
push_link_head(plink, 3);
push_link_head(plink, 11);
push_link_head(plink, 56);
push_link_head(plink, -1);
push_link_head(plink, 7);
push_link_head(plink, 77);
// print_list(plink);
push_tail(plink,0);
// print_list(plink);
// pop_link_head(plink);
// pop_link_tail(plink);
//
Link_Node_t *p ;
// p = find_list_element(plink,2);
// updata_list_element(plink,p,10);
// print_list(plink);
// delete_list(plink);
// p = find_midlist(plink);
// p = find_last_num(plink,4);
// updata_list_element(plink,p,10);
// delete_list_element(plink,8);
// p = find_last_num_fa(plink,9);
// updata_list_element(plink,p,10);
// invert_list_element(plink);
insert_list_element(plink);
print_list(plink);
return 0;
}
双向链表
#ifndef _BOTHWAY_H_
#define _BOTHWAY_H_
#include<head.h>
typedef struct stu
{
int id;
char name[20];
double score;
}DataType;
typedef struct dnode
{
DataType data;
struct dnode *ppre;
struct dnode *pnext;
}DLink_Node_t;
typedef struct dlink
{
DLink_Node_t *phead;
int clen;
pthread_mutex_t mutex;
}DLink_t;
extern DLink_t * create_doulink(void);
extern int is_empty_bothway(DLink_t *pdoulink);
extern int push_doulink_head(DLink_t *pdoulink,DataType data);
extern void print_bothway_list(DLink_t *pdoulink,int dir);
extern int push_doulink_tail(DLink_t *pdoulink,DataType data);
extern void delete_doulink_head(DLink_t *pdoulink);
extern void delete_doulink_tail(DLink_t *pdoulink);
extern DLink_Node_t *find_doulink_element(DLink_t *pdoulink,char *name);
extern void updata_doulink_element(DLink_t *pdoulink,char *name,double score);
extern void destory_doulist(DLink_t *pdoulink);
#endif
#include"bothway.h"
//创建头
DLink_t * create_doulink(void)
{
DLink_t *pdoulink = malloc(sizeof(DLink_t));
if(pdoulink == NULL)
{
perror("fail to malloc\n");
return NULL;
}
pdoulink->phead = NULL;
pdoulink->clen = 0;
pthread_mutex_init(&(pdoulink->mutex),NULL);
return pdoulink;
}
//判空列表
int is_empty_bothway(DLink_t *pdoulink)
{
return NULL == pdoulink->phead;
}
//头插
int push_doulink_head(DLink_t *pdoulink,DataType data)
{
DLink_Node_t *pnode = malloc(sizeof(DLink_Node_t));
if(pnode == NULL)
{
perror("fail to malloc_node");
return -1;
}
pnode->data = data;
pnode->ppre = NULL;
pnode->pnext = NULL;
if(is_empty_bothway(pdoulink))
{
pdoulink->phead = pnode;
}
else
{
pnode->pnext = pdoulink->phead;
pdoulink->phead->ppre = pnode;
pdoulink->phead = pnode;
}
pdoulink->clen++;
return 0;
}
//遍历
void print_bothway_list(DLink_t *pdoulink,int dir)
{
if(is_empty_bothway(pdoulink))
{
return ;
}
DLink_Node_t *p = pdoulink->phead;
if(pdoulink->clen == 1)
{
printf("%2d %s %f\n",p->data.id,p->data.name,p->data.score);
}
else if(dir)
{
while(p != NULL)
{
printf("%2d %s %f\n",p->data.id,p->data.name,p->data.score);
p = p->pnext;
}
}
else
{
while(p->pnext != NULL)
{
p = p->pnext;
}
while(p != NULL)
{
printf("%2d %s %f\n",p->data.id,p->data.name,p->data.score);
p = p->ppre;
}
}
}
//尾增
int push_doulink_tail(DLink_t *pdoulink,DataType data)
{
DLink_Node_t *pnode = malloc(sizeof(DLink_Node_t));
if(pnode == NULL)
{
perror("fail to malloc_node");
return -1;
}
pnode->data = data;
pnode->ppre = NULL;
pnode->pnext = NULL;
DLink_Node_t *p = pdoulink->phead;
while(p->pnext != NULL)
{
p = p->pnext;
}
p->pnext = pnode;
pnode->ppre = p;
pdoulink->clen++;
return 0;
}
//头删
void delete_doulink_head(DLink_t *pdoulink)
{
DLink_Node_t *p = pdoulink->phead;
if(is_empty_bothway(pdoulink))
{
return ;
}
if(pdoulink->clen == 1)
{
pdoulink->phead = p->pnext;
free(p);
pdoulink->clen--;
}
else
{
pdoulink->phead = p->pnext;
p->pnext->ppre = NULL;
pdoulink->clen--;
free(p);
}
}
//尾删
void delete_doulink_tail(DLink_t *pdoulink)
{
if(is_empty_bothway(pdoulink))
{
return ;
}
else if(pdoulink->clen == 1)
{
delete_doulink_head(pdoulink);
return ;
}
else
{
DLink_Node_t *p = pdoulink->phead;
while(p->pnext->pnext != NULL)
{
p = p->pnext;
}
p->pnext = NULL;
pdoulink->clen--;
free(p->pnext);
}
}
//查找
DLink_Node_t *find_doulink_element(DLink_t *pdoulink,char *name)
{
DLink_Node_t *p = pdoulink->phead;
while(p != NULL)
{
if(strcmp(p->data.name,name) == 0)
{
return p;
}
p = p->pnext;
}
return NULL;
}
//更新分数
void updata_doulink_element(DLink_t *pdoulink,char *name,double score)
{
DLink_Node_t *p = pdoulink->phead;
while(p != NULL)
{
if(strcmp(p->data.name,name) == 0)
{
p->data.score = score;
}
p = p->pnext;
}
}
//销毁
void destory_doulist(DLink_t *pdoulink)
{
if(is_empty_bothway(pdoulink))
{
return ;
}
while(pdoulink->clen > 0)
{
delete_doulink_head(pdoulink);
}
free(pdoulink);
}
总结:
找节点时有两种情况
while(p != NULL) 或 while( p -> pnext != NULL)
{ {
p = p->pnext; p = p->pnext;
} }
情况1时出循环就不能操作了,出循环p就指向空了,循环内可以找到最后一个节点
情况2时出循环才能指向最后一个节点,再进行操作