線性表-順序存儲結構-實現取交集A=A∪B

今天實現數據結構課本上一個很簡單的算法~

功能:實現A=A∪B運算。

           由用戶輸入A,B兩個集合內容,算法求出兩個集合並集並輸出。

算法結構:線性表的順序存儲結構。(數組)


線性表的順序存儲結構

結構體

typedef struct{
    char * array;//存儲空間基地址
    int length;//當前長度(數組中已存取的數據個數)
    int listsize;//當前分配的存儲容量(數組能存儲的數據總個數)
}SqList;

便於內存分配的宏定義:

# define LIST_INIT_SIZE 5//線性表存儲空間的初始分配量
# define LISTINCREAMENT 1//線性表存儲空間的分配增量

本程序用到的所有函數聲明:

int InitList_Sq(SqList *a);//初始化順序存儲線性表
int ListEnlarge_Sq(SqList *a);//增大順序存儲線性表存儲空間
int ListInsert_Sq(SqList * a,int i,int e);//插入元素
int LocateElem_Sq(SqList L,int e,int (*compare)(int,int));//定位滿足要求的線性表中元素
void union_ab(SqList * a,SqList * b);//求並集函數
void display_array(SqList a);//顯示線性表內容
void Input_array(SqList * a);//用戶輸入線性表內容數據
int GetElem(SqList a,int i,int *e);//找到所需次序的元素
int equal(int a,int b);//數值比較函數

下面具體說明每個函數的編寫!

1.  int InitList_Sq(SqList *a)

作用:初始化數組。

int InitList_Sq(SqList *a)
{  

a->array=(char *)malloc((LIST_INIT_SIZE)*sizeof(char));//分配基地址
if(!a->array) exit(1);//未分配空間成功
a->length=0;//當前儲存元素的長度
a->listsize=LIST_INIT_SIZE;//總空間
return 0;

}

2. void Input_array(SqList * a)

作用:由用戶輸入線性表內容。

       (這裏規定輸入不同元素之間要敲個空格,輸入完了要打個回車!)

void Input_array(SqList * a)
{
    printf("Please input array.\n");
    int i;//計數輸入元素個數
    char ch,sh;
    for(i=0; ;i++)
    {

        ch=getchar();//用戶輸入字符
        a->array[i]=ch;
        a->length++;

        sh=getchar();//用戶在輸入不同元素間敲入空格
        if(sh==10)//判斷輸入的元素是不是回車
        {
            break;
        }
       
        if(a->length==a->listsize)//增大數組內存
        {
            ListEnlarge_Sq(a);
        }

    }
    printf("You have finished the input.\n");

}

畫個重點呀~

請關注1.getchar()函數的用法,空格等非用戶想輸入的數據也會被讀取,注意處理!

            2.判斷是否輸入回車的方法。(關於字符和ASCII表..)

3.int ListEnlarge_Sq(SqList *a)

int ListEnlarge_Sq(SqList *a)
{
    char * newbase;//分配一個新基地址
    newbase=(char*)realloc(a->array,sizeof(char)*(a->listsize+LISTINCREAMENT));//重新分配
    if(!newbase) return(1);//分配失敗
    a->array=newbase;//基地址移過去
    a->listsize=a->listsize+LISTINCREAMENT;//總內存增大
}

關注:整個函數的用法!!!尤其是realloc用法!

4.void display_array(SqList a)

作用:打印出線性表內容。

void display_array(SqList a)
{
    int i;
    for(i=0;i<a.length;i++)
    {
        printf("%c ",a.array[i]);
    }
}

 

5.int GetElem(SqList a,int i,int *e)

作用:取得線性表a中第I個元素,並賦值給e。

int GetElem(SqList a,int i,int *e)
{
   if(i>a.length||i<=0)
   {
       printf("Can't get element.");
       return 1;
   }//不合法I值
   char ch;
   ch=a.array[i-1];
   *e=atoi(&ch);
    return 0;
}

 關注:atoi()函數的用法。

將字符串char*轉換爲對應的int整數值。

如5(char)→5(int),而非ascii表中對應的整數值(顯然並不是你想表達的)。

這裏的另一個實現方法:若是char ch = '6';你想讓int a = ch 也爲6,可以採用減法:

如 a=ch-'0';

注意該函數是對於字符串char[](即一堆字符)的操作,所以這裏先用ch取得了a.array[]字符串中的所需的一個字符。

6.int equal(int a,int b)

簡簡單單就是真的數值比較函數,根據需要可以改成其他的大於小於什麼的。

函數用來判斷某元素滿足的條件。

int equal(int a,int b)
{
    if(a==b)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

7.int ListInsert_Sq(SqList * a,int i,int e)
作用:在順序線性表a中第i個位置之前插入新的元素e

int ListInsert_Sq(SqList * a,int i,int e){
//在順序線性表a中第i個位置之前插入新的元素e
if(i<1||i>a->length+1){
    return 1;
}//i值不合法
char * newbase;
if(a->length>=a->listsize)//當前存儲空間已滿,再分配增量
{
    newbase=(char *)realloc(a->array,(a->listsize+LISTINCREAMENT)*sizeof(char));
    if(!newbase) exit(1);
    a->array=newbase;
    a->listsize+=LISTINCREAMENT;

}
char *q, *p;
q=&(a->array[i-1]);//注意第幾個元素與下標的關係
 //移動數組元素:從後往前移動
for(p=&(a->array[a->length-1]);p>=q;--p){ //數組中地址連續,也可以比大小

*(p+1)=*(p);//插入位置與其之後的元素後移
}
q=itoa(e,q,10);
a->length++;
return 0;

}

關注:1.數組中元素的移動方法。

2.char*=itoa(int,char*,int)函數用法,將int型整數轉換爲對應的char型字符。

最後那個int是10進制/2進制/...

3.補充:c語言中所有的子函數是平行關係,意味着它們可以互相引用,但不可互相嵌套定義。

 

 8.int LocateElem_Sq(SqList L,int e,int (*compare)(int,int))

作用:在順序表中查找第一個值與e 滿足條件compare()的元素的位序(1,2......)
若找到,返回位序,否則返回0.

int LocateElem_Sq(SqList L,int e,int (*compare)(int,int)){

int i=1;
char  p;
int a;

p=L.array[0];
a=atoi(&p);

for(;i<=L.length&&!(*compare)(a,e);i++)
{
   p=L.array[i];
    a=atoi(&p);
}
if(i<=L.length) return i;
else return 0;

}

關注:atoi用法(包括對字符or字符串的處理) 、int ,char轉換。

          函數指針的使用!

9.void union_ab(SqList * a,SqList * b)

作用:求並集。

 

void union_ab(SqList * a,SqList * b){
    int a_len,b_len;
    a_len=a->length;
    b_len=b->length;

    int i;
    int e;

    for(i=1;i<=b_len;i++){
        GetElem(*b,i,&e);
        if(!LocateElem_Sq(*a,e,equal))
        {
        ListInsert_Sq(a,a->length+1,e);//插入時就改變了a.length
        }
    }
}

關注:++和+1的區別。

如在If語句中,a+1僅表示if中使用的爲該表達式的值,a原值不改變。但a++語句會改變a的值。

 

10.主函數main

int main()
{

c=getchar();

SqList a,b;
InitList_Sq(&a);
InitList_Sq(&b);

Input_array(&a);
Input_array(&b);


printf("\nLet's display.\n");

display_array(a);
printf("alength %d",a.length);

printf("\n");

display_array(b);
printf("blength %d",b.length);

union_ab(& a,& b);

printf("\nLet's display the union.\n");

display_array(a);
printf("\ntotal length %d",a.length);

return 0;
}

okkkkkkkk程序寫完啦~運行還是很成功的!

運行結果:

奧裏給!

 

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