数据结构(2)
前面已经介绍过单向链表行为有哪些链表行为,在成功创建链表对象之后,我们开始完成其他链表行为。
一、插入数据
(1)头插
int insert_link_head(Link_t *plink,Data_type_t data)
{Node_t *pnode = malloc(sizeof(Node_t));if(NULL == pnode){printf("malloc error");return -1;}pnode->data = data;pnode->pnext = NULL;pnode->pnext = plink->phead;plink->phead = pnode;plink->clen++;return 0;}
(2)尾插
int insert_end_link(Link_t *plink, Data_type_t data)
{Node_t *pnode = malloc(sizeof(Node_t));if(pnode == NULL){return -1;}pnode->data = data;pnode->pnext = NULL;if(NULL == plink->phead){plink->phead = pnode;plink->clen++;return 0;}Node_t *ptmp = plink->phead;while(ptmp->pnext != NULL){ptmp = ptmp->pnext;}ptmp->pnext = pnode;plink->clen++;return 0;}
二、删除数据
(1)头删
int link_for_delete(Link_t *plink)
{if(is_empty_link(plink)){return -1;}Node_t *ptmp = plink->phead;plink->phead = ptmp->pnext;free(ptmp);plink->clen--;return 0;}
(2)尾删
int link_delete_end(Link_t *plink)
{Node_t *ptmp = plink->phead;if(ptmp == NULL){printf("error\n");return -1;}else if(plink->phead == NULL){link_for_delete(plink);return 1;}while(ptmp->pnext->pnext != NULL){ptmp = ptmp->pnext;}free(ptmp->pnext);ptmp->pnext = NULL;plink->clen--;return 1;}
三、修改数据
int change_link(Link_t *plink, Data_type_t olddata, Data_type_t newdata)
{Node_t *ptmp = plink->phead;while(ptmp != NULL){if(ptmp->data == olddata){ptmp->data = newdata;return 1;}else{ptmp = ptmp->pnext;}}return 0;
}
四、查找数据
除了常规查找方法之外,我们也可以利用快慢指针法进行查找,快指针一次走两步,慢指针一次走一步,快指针走到结尾时,慢指针正好走到中间值,我们利用这个原理,寻找倒数第k个元素时,只需让快指针先走k步,然后二者共同走直至结尾即可。
Node_t *find_link(Link_t *plink, Data_type_t mydata)
{Node_t *ptmp = plink->phead;while(ptmp != NULL){if(mydata == ptmp->data){return ptmp;}else{ptmp = ptmp->pnext;}}return NULL;
}
//快慢指针法
Node_t *find_mid_node(Link_t *plink)
{if(is_empty_link(plink)){return NULL;}Node_t *pfast = plink->phead;Node_t *pslow = pfast;while(pfast != NULL){pfast = pfast->pnext;if(pfast == NULL){break;}pfast = pfast->pnext;pslow = pslow->pnext;}return pslow;
}
//快速查找倒数第k个
Node_t *find_k_node(Link_t *plink, Data_type_t data)
{if(is_empty_link(plink)){return NULL;}Node_t *pfast = plink->phead;Node_t *pslow = pfast;int i = data;while(i--){if(pfast != NULL){pfast = pfast->pnext; }else{return NULL;}}while(pfast != NULL){pfast = pfast->pnext; pslow = pslow->pnext;}return pslow;
}
五、销毁数据
int destory_link(Link_t *plink)
{while(!is_empty_link(plink)){link_for_delete(plink); }free(plink);plink = NULL;
}
六、判断有环链表
有环列表:该列表中没有空指针,最后一个节点可以指向之前的任何值;
循环列表:与有环列表定义相同,不同点在于最后一个指针指向首结点,使链表变成环形,循环链表是特殊的有环列表。
int is_loop_link(Link_t *plink)
{Node_t *pfast = plink->phead;Node_t *pslow = plink->phead;if(plink->phead == 0 || plink->phead->pnext == NULL){return 0;}while(pfast != NULL && pfast->pnext != NULL){pslow = pslow->pnext;pfast = pfast->pnext->pnext;if(pfast == pslow){return 1;}}return 0;
}