创建节点
// 创建一个节点,data为一个节点的有效数据
struct node *creat_node(int data)
{
struct node *p = (struct node *)malloc(1*NODE_LEN);
if(NULL == p){
printf("fail to malloc.\n");
return NULL;
}
memset(p, 0, NODE_LEN);
p->data = data;
p->pNext = NULL;
return p;
}
插入链表
头插法
// 从头部插入节点,data为一个节点的有效数据
void Head_Add_Node(struct node *pH, struct node *new)
{
new->pNext = pH->pNext;
pH->pNext = new;
pH->data += 1;
}
尾插法
// 从尾部插入节点,data为一个节点的有效数据
void Behind_Add_Node(struct node *pH, struct node *new)
{
int cnt = 0;
struct node *p = pH;
while(NULL != p->pNext){
p = p->pNext;
cnt++;
}
p->pNext = new;
pH->data = cnt+1;
}
遍历链表
void traverse_list(struct node *pH)
{
int cnt = 0;
struct node *p = pH;
while(NULL != p->pNext){
p = p->pNext;
cnt++;
printf("第%d个链表的数据为:%d\n", cnt, p->data);
}
}
删除节点
/*
** 删除节点。参数:头节点,根据数据删除节点
** 参数:删除成功返回0,要找到节点不存在返回-1
*/
int delete_list(struct node *pH, int data)
{
struct node *p = pH;
struct node *pSeek = pH;
struct node *pPrev = NULL;
while(NULL != pSeek->pNext){ // 判断data是否在链表的某个节点里
if(pSeek->pNext->data != data){
pSeek = pSeek->pNext;
if(NULL == pSeek->pNext){
return -1;
}
}
else{
break;
}
}
while(NULL != p->pNext){ // 第二步,确认data在这个链表某个节点里
//
if(p->pNext->data == data){ // p的下一个节点是待删节点
//
pPrev = p->pNext; // 保存待删节点,方便后面free()掉
if(NULL == p->pNext->pNext){ // p是尾节点
free(p->pNext);
p->pNext == NULL;
}
else{
p->pNext = p->pNext->pNext;
free(pPrev);
}
}
else{
p = p->pNext;
}
}
return 0;
}
链表反转
算法:采用头插法插到新链表,最后返回新链表
// 单链表的逆序
struct node *inverse_link(struct node *pH)
{
struct node *p = pH;
struct node *pInverse = creat_node(0);
struct node *pIntermediate = NULL;
/*if((NULL == p) || (NULL == p->pNext)){
return NULL;
}*/
while(NULL != p->pNext){
//Head_Add_Node(struct node *pH, struct node *new)
// 没有有效节点或只有一个节点的情况
p = p->pNext;
pIntermediate = p;
//pIntermediate->pNext = NULL;
Head_Add_Node(pInverse, pIntermediate);
}
return pInverse;
}