今天實現數據結構課本上一個很簡單的算法~
功能:實現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程序寫完啦~運行還是很成功的!
運行結果:
奧裏給!