以前没关心过存储结构。一个数组搞天下。大不了范围广一点。没什么大不了。自从递归的全排列算法因为递归太多影响到效率的时候不得不用链表了。搞了两天。折腾了两天。
因为算法的缘故。每次在头结点插入。在头结点删除。极少数在尾结点删除。并且无法估计链表个数。目前已经超过21亿多了。废话不多说。整原理。下面是我的解决方法。也可以用其他的方法。
链表的声明
- typedef struct HNode{
-
int using;
-
struct HNode *next;
-
}HNode,*HList;
-
HList Head;//头结点
其实这里的HNode一般用不上。全部用HList完成就可以了。
Head是头结点。申明了。但是没有创建。
创建头结点和其他结点
- Head=malloc(HNode);
-
HList node1=malloc(HNode);
-
if(Head==NULL||node1==NULL)
-
printf("内存不够用了");
删除时带来的问题。
因为我的操作都是在头和尾完成。删除的时候分别带来了下面的问题。
1.头删除的错误代码
- //删除node1
-
HList node2=node1;
-
node1=Head->next;
-
free(node2);
因为之前node1就是Head->next;这里一下子两个都删除了。
索性写丑一点的正确代码。
- //删除node1
-
HList node2=node1;
-
node1=Head;
-
free(node2);
-
node1=Head->next;
第二行是为了node1.有所指,这样不会被free掉。而除了头结点后面的全部说不清楚。索性放到头结点。
2.尾指针的错误删除
如不以为尾指针不是尾指针采用pre->next=node1->next;也行。前提是全部指针在创建的时候必须强制node->next=NULL;
产生错误删除的原因是新的尾指针指向的是一个废地址。但是确实存在这个地址。如果需要使用新的尾指针的next的时候是未初始化的值而不是pre->next==NULL
例子
- //假设现在处于这样的状态
-
//Head->node1->node2->....->pre->nodeL->NULL;
-
//最后一个结点是nodeL。之前的一个是pre
-
free(nodeL);
-
HList A=Head;
-
while(A->next!=pre)
-
A=A->next;
-
//A指向pre的前驱
-
A=A->next;//A现在指向pre
-
if(A->next==NULL||A->next)
-
printf("OK");
这里的OK是打印不出来的。
正确的删除的方法是
- freenode(HList node1){
-
HList node2=node1;
-
node1=Head;
-
while(node1->next!=node2)
-
node1=node1->next;
-
free(node2);
-
node1->next=NULL;
-
}
这样就能保证尾结点指向的是NULLl了。也能打印整个链表的值了。
阅读(1944) | 评论(0) | 转发(1) |