/************************************************************************/
/* 功能:刪除連結串列A中在B中出現的節點 就是求解(A-B)
exp:
A中元素10個:2,3,6,7,9,14,56,45,65,67
B中元素8個: 3,4,7,11,34,54,45,67
則 A-B後,A中的元素為6個
2 6 9 14 56 65 */
/************************************************************************/
/************************************************************************/
/* 出現的問題:
1.陣列名的問題 int a[4];
sizeof(a)表示整個陣列的大小=sizeof(int)*4,sizeof(a[0])表示一個元素的位元組數為sizeof(int)
但是我在傳遞到一個函式中,將該陣列名(也就是指標)傳遞給到另一個函式中,
func(a);
void func(int *dataa)
{
int x=sizeof(dataa);
printf("%d",x); //結果為 x=4,並不是40.
}
2.邏輯的問題
見程式碼錯誤處
3.判別的問題
while(cur_b!=NULL && cur_a->data!=cur_b->data )
第一個檢測時否是 滿足cur_b!=NULL,如果不滿足,後面就不檢測了,如果
while( cur_a->data!=cur_b->data && cur_b!=NULL )就出現問題,記憶體洩露
因為一輪查詢完b後,cur_b=NULL了。此時cur_b->data是沒有的,只讀錯誤。
*/
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
}listnode;
void CreateList(listnode *head,int nodenum,int *data);
void printflist(listnode *head);
void DeleElement(listnode *lista,listnode *listb,int *leave,int dataa);
void main()
{
int dataa[]={2,3,6,7,9,14,56,45,65,67};
int datab[]={3,4,7,11,34,54,45,67,2};
listnode *head1=(listnode *)malloc(sizeof(listnode));
listnode *head2=(listnode *)malloc(sizeof(listnode));
if(head1==NULL|| NULL==head2)
{
printf("頭結點malloc分配失敗\n");
exit(-1);
}
CreateList(head1,sizeof(dataa)/sizeof(dataa[0]),dataa);
printf("連結串列A的元素有%d個:\n",sizeof(dataa)/sizeof(dataa[0]));
printflist(head1);
CreateList(head2,sizeof(datab)/sizeof(datab[0]),datab);
printf("連結串列B的元素有%d個:\n",sizeof(datab)/sizeof(datab[0]));
printflist(head2);
int leave;
DeleElement(head1,head2,&leave,sizeof(dataa)/sizeof(dataa[0]));
printf("則 A-B後,A中的元素為%d個\n",leave);
printflist(head1);
}
void CreateList(listnode *head,int nodenum,int *data)
{
listnode *h=head,*pre=h,*newnode;
for(int i=0;i<nodenum;i++)
{
if(NULL==(newnode=(listnode *)malloc(sizeof(listnode))))//開闢一個新節點
{
printf("malloc申請失敗");
return ;
}
newnode->data=data[i];
pre->next=newnode;
pre=newnode;
}
pre->next=NULL;
return ;
}
void printflist(listnode *head)
{
listnode *p=head->next;
while(p!=NULL)
{
printf("%4d",p->data);
p=p->next;
}
printf("\n");
return ;
}
void DeleElement(listnode *lista,listnode *listb,int *leave,int dataa)
{
//連結串列a刪除b在a中出現的元素
listnode *pre_a=lista,*cur_b=listb->next,*p;
int count=0;
while(pre_a->next!=NULL) //控制整個流程
{
while(cur_b!=NULL && pre_a->next->data!=cur_b->data ) //將連結串列b中的元素在a中遍歷
cur_b=cur_b->next; //目的 找到刪除節點pre位置
if(NULL!=cur_b) //b遍歷完一遍了 找到了
{
p=pre_a->next;
pre_a->next=p->next;
free(p);
count++; //用Pre做的話,找到後不要更新pre=pre->next
}
else
pre_a=pre_a->next; //a中元素後繼一位
cur_b=listb->next; //重新從第一個元素開始
}
*leave=dataa-count; //返回剩下a中元素個數
return ;
}
/************************************************************************/
/* 問題:
這裡發生了個細節問題,在C中,求陣列的大小,是用單目運算子sizeof()來做,
int a[3]; sizeof(a)=3*sizeof(int).但是在函式傳遞中,將a傳遞給其他的函式,這時候
就是指標了,並且a代表的是第一個元素的地址。 */
/************************************************************************/
void func(int *a)
{
printf("陣列a的大小為:sizeof(a)=%d\nsizeof(a[0])=%d\n",sizeof(a),sizeof(a[0]));
}
void main()
{
int a[4];
printf("陣列a的大小為:sizeof(a)=%d\nsizeof(a[0])=%d\n傳遞函式後\n",sizeof(a),sizeof(a[0]));
func(a);
}