算法之单向链表
算法之单向链表
1 链表结构体
/*结构体*/
typedef struct _link_node
{
struct _link_node* next;
int data;
}link_node;
- 注意点
- 定义结构体时,最好的顺序是由大到小的顺序定义结构体成员,如上,我先定义了
一个指针类型,然后又定义了一个 int类型变量,它会占用16个字节,如果你顺序
调过来,还是16个字节,但是它的效率会低很多,为什么会这样了?请看数据对齐相
关内容; 《数据对齐详解》
2 创建链表
/*1.创建链表*/
link_node* creat_node(int value)
{
link_node* pLinkNode;
pLinkNode = (link_node*)malloc(sizeof(link_node));
if(NULL ==pLinkNode)
printf("Failt");
pLinkNode->data = value;
pLinkNode->next = NULL;
return pLinkNode;
}
3 打印链表
/*2.打印链表*/
void print_node(link_node* pLinkNode)
{
if(NULL == pLinkNode)
{
printf("\n");
return ;
}
printf("%d\t",pLinkNode->data);
printf("p2=%p\n",pLinkNode);
print_node(pLinkNode->next);
}
4 插入链表
/*4.链表插入数据*/
/*
插入位子从 0 开始
*/
int _insert_node(link_node** pToNode,
link_node* pDataNode, int place)
{
if( NULL == *pToNode )
{
printf("超出链表长度,插入失败\n");
return -1;
}
if(1==place )
{
pDataNode->next = (*pToNode)->next;
(*pToNode)->next=pDataNode;
return 0;
}
_insert_node(&(*pToNode)->next, pDataNode, place-1);
}
void insert_node(link_node** pToNode, int place, int value)
{
link_node* pDataNode;
pDataNode = creat_node(value);
if(0 == place)
{
pDataNode->next = *pToNode;
*pToNode = pDataNode;
return;
}
if(place<0 ) /*和法性有问题,插入位子容易过大*/
{
printf("插入位子错误");
return;
}
_insert_node(pToNode, pDataNode, place);
}
5 删除链表
/*5.删除链表*/
#if 1
/* 递归方法 */
void delete_node(link_node** pNode)
{
link_node* pLinkNode;
if(NULL==pNode || NULL==*pNode)
{
printf("afa\n");
return;
}
printf("1\n");
pLinkNode = *pNode;
*pNode=(*pNode)->next;
free(pLinkNode);
//printf("pdata=%d\tpnext=%p\n",pLinkNode->data, pLinkNode->next); //测试
delete_node(pNode);
}
#else
/*普通方法*/
void delete_node(link_node** pNode)
{
link_node *pLinkNode;
while(NULL != *pNode)
{
pLinkNode=*pNode;
*pNode=(*pNode)->next;
free(pLinkNode);
/*调试信息*/
//printf("pnp=%p\tpdp=%p\t", pLinkNode,&(pLinkNode->data) );
//printf("pdata=%d\tpnext=%p\n",pLinkNode->data, pLinkNode->next);
}
}
#endif
- 注意事项
- 在我调试删除链表时发现一个奇怪现象
本奇葩现象在单向链表中发现
1.在带有指针域和数据域结构体中,用malloc()函数分配空间,再用free()函数
释放空间,在释放空间过程中,被释放空间的指针域会产生一个随机数,而数据域的
值不会发生任何改变,如果你通过被释放空间的指针域访问下一个地址,你可以在
数据域中看到一个随机的数据,但指针域所指的地址为NULL。 - 测试代码
#include
#include typedef struct _link_node { struct _link_node* next; int data; }link_node; int main() { link_node* pLinkNode; link_node* pNode; pLinkNode = (link_node*)malloc(sizeof(struct _link_node)); pNode = (link_node*)malloc(sizeof(struct _link_node)); pLinkNode->data = 16; pNode->data = 6; pLinkNode->next = pNode; printf("%p\n",pNode); printf("前:pnp=%p\tpdp=%p\t", pLinkNode,&(pLinkNode->data) ); printf("pdata=%d\tpnext=%p\n",pLinkNode->data, pLinkNode->next); free(pNode); free(pLinkNode); printf("后:pnp=%p\tpdp=%p\t", pLinkNode,&(pLinkNode->data) ); printf("pdata=%d\tpnext=%p\n",pLinkNode->data, pLinkNode->next); printf("ndata=%d\t",(pLinkNode->next)->data); printf("np=%p\n",(pLinkNode->next)->next); return 0; }
6 删除结点
/*6.删除结点*/
void delete_one_node(link_node** pNode, int place)
{
link_node* pNext;
if(NULL==*pNode || NULL==pNode)
{
printf("超出链表,删除失败\n");
return;
}
if(1== place)
{
*pNode=(*pNode)->next;
return;
}
if(2 == place)
{
pNext=(*pNode)->next;
(*pNode)->next = pNext->next;
free(pNext);
return;
}
delete_one_node(&(*pNode)->next,place-1);
}
7 查找数据
/*7. 查找数据*/
link_node* find_data(link_node** pNode, int value)
{
if(NULL==(*pNode))
{
printf("not found !\n");
return NULL;
}
if(value == ((*pNode)->data))
{
return *pNode;
}
find_data(&(*pNode)->next, value);
}
8 统计数据
/*8.统计数据*/
int count_node(link_node* pLinkNode)
{
if(NULL==pLinkNode)
return 0;
return 1+count_node(pLinkNode->next);
}
9 测试代码
void main()
{
link_node* pLinkNode;
link_node* pNode;
int n;
pLinkNode = creat_node(5);
add_data(&pLinkNode, 7);
add_data(&pLinkNode, 8);
add_data(&pLinkNode, 9);
print_node(pLinkNode);
delete_node(&pLinkNode);
print_node(pLinkNode);
}
浙公网安备 33010602011771号