實戰資料結構(2)_兩個單連結串列間的刪除操作

YunShell發表於2013-08-22

/************************************************************************/
/* 功能:刪除連結串列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);
}



相關文章