C語言用順序表實現集合的交、並、補、差

數據結構實驗課第一節就是實現如題所示功能,最後結果雖然實現了,但是代碼不夠elegant,看起來不夠漂亮,該篇文章主要想記錄一下差距

my answer
my teacher’s answer 交1
my teacher’s answer 交2
my teacher’s answer 並、補、差

1、引用 & 的問題

在一些函數參數傳參時候,有的是(SqList LA)還有的是(SqList &LB),後者是引用,表示在該函數中可以更改LB內的值,前者表示不可更改,沒有&符號表示僅僅是形參。
question:我在使用的時候不分是否可以更改,全部都加上了&符號

void Inter(SqList La, SqList Lb, SqList &Lc)

應該這麼寫↑,在LA和LB不需要被修改的時候,不要加&符號

2、忘記銷燬

DestroyList_Sq(La);
DestroyList_Sq(Lb);
DetroyList_Sq(Lc);
DetroyList_Sq(Ld);
DetroyList_Sq(Le);
DetroyList_Sq(Lf);

所有在主函數中initList在最後都要銷燬!!

3、printf(*********************** Result **************)的使用

printf("************* Input A ***************\n");
printf("************* Input B ***************\n");
printf("\n************* Result ****************\n");
printf("*************************************\n");

這些長句的輸出,可以使得程序輸出更加清晰,把輸入和輸出用Result分開,把集合A與集合B用input A、input B分開,把最後的無效輸出和**** \n分開

4、主函數邏輯結構不夠清晰

通過比較可以明顯的感覺到我自己寫的void中有很多繁雜的、不易讀的部分

merge(A, B, add);
inersect(A, B, diff);
Minus(A, B, aminusb);
Minus(B, A, bminusa);
printf("\n************* Result ****************\n");
      
      
        
        	printf("A = {"); // 輸出集合A
       	ListTraverse_Sq(La);
       	printf("}\n"); 
       	
   	printf("B = {"); // 輸出集合B
       	ListTraverse_Sq(Lb);
       	printf("}\n"); 
       	
  	printf("A U B = {"); // 輸出集合C(A並B)
       	ListTraverse_Sq(Lc);
       	printf("}\n"); 
       	
   	printf("A * B = {"); // 輸出集合D(A交B)
       	ListTraverse_Sq(Ld);
       	printf("}\n"); 
       	
   	printf("A - B = {"); // 輸出集合E(A-B)
       	ListTraverse_Sq(Le);
       	printf("}\n"); 
       	
  	printf("B - A = {"); // 輸出集合F(B-A)
       	ListTraverse_Sq(Lf);
       	printf("}\n"); 
       	
       	printf("*************************************\n");

把函數調用和相應的函數輸出放在一起,同時加註釋,比函數調用放一起、輸出放一起看起來要清晰很多

5、內容輸出

可以把所有的輸出都寫成一個函數,每次直接調用就可以輸出,比我寫成這樣要清爽很多:

for(i = 0; i < add.length; i++){
printf("%d ", add.elem[i]){
}

6、函數文件中提供的一些函數沒有很好地使用

//求交集
       void Inter(SqList La, SqList Lb, SqList &Lc)
       {
       	int i, j = 0;
       	ElemType e;
  	for (i = 1; i <= ListLength_Sq(La); i++)
       	{
       		GetElem_Sq(La, i, e);  //取集合A中的元素
       		if (LocateElem_Sq(Lb, e))  //在集合B中存在該元素
       		{
       			j++;
       			ListInsert_Sq(Lc, j, e); //插入到集合C中
       		}
       	}
       }
void intersect(SqList &a, SqList &b, SqList &diff){
       	int i, j = 0;
   	for(i = 0; i < ListLength_Sq(a); i++){
       		if(LocateElem_Sq(b, a.elem[i])){
       			diff.elem[j++] = b.elem[i];
       			diff.length++;
       		}
       	}
       }

7、順序表初始化可以寫成一個函數

順序表初始化應該寫成一個函數,在主函數中調用這個函數然後輸入相應的值,而不是把輸入寫在主函數裏,寫在主函數裏那麼LA和LB都要寫一部分重複的代碼,調用函數直接寫函數名傳入參數即可

printf("請依次輸入集合A元素的數值:");
       	for(i = 0; i < na; i++){
       		scanf("%d", &a[i]);
       		A.elem[i] = a[i];
       		A.length++;
       	}
void InputElement(SqList &L)   //輸入集合元素到線性表L中
       {
       	int i, num, e;
       	
   	printf("num  = ");
       	scanf("%d", &num);
       	
       	printf("elem = ");
       	for(i = 1; i <= num; i++)
       	{
       		scanf("%d", &e);
       		ListInsert_Sq(L, i, e); 
       	}
       }

8、註釋

在使用函數文件中的函數以及自己寫一個函數的時候,最好在後面加上相應的註釋(不要加太多,加重點就行)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章