數組是一種常用的數據結構。高級程序設計評議都提供了支持數組的基本方法。數組分靜態數組和動態數組。靜態數組和動態數組的實現機制相似,只是在程序設計時向系統申請內在空間的時間不同。
數組
數組是n(n>1)個相同數據類型的數據元素a0,a1,a2,…,a(n-1)構成的佔用一塊地址連續的內存單元有限序列。
數據集合:
數據的數據集合可以表示爲a0,a1,a2,…,a(n-1),每個數據元素的數據類型爲抽象數據元素類型DataType。
操作集合:
(1).求數組元素個數ArrayLength(D):函數返回數組D的元素個數。
(2).存數組元素Storage(D,i,x):把數據元素x存入下標爲i的數組D中,其約束條件爲0<=i<=ArrayLength(D) – 1.
(3).取數組元素Get(D,i,x):取出下標爲i的數組D中的元素賦給參數x,其約束條件爲0<=i<=ArrayLength(D)-1
動態數組
數組有靜態數組和動態數組兩種,靜態數組在定義時就必須給出數組個數,因爲編譯系統要在軟件編譯時就爲靜態數組分配內存空間。動態數組是在需要存儲單元空間時纔給出數組的具體個數。高級程序設計語言一般都提供支持用戶定義動態數組的函數或運算符。
C語言提供建立和撤消動態數組的函數malloc()函數,calloc()函數,free()函數
例1:
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
int *a,n = 10,i;
//動態申請n個int類型的內存空間,若內存空間不足則退出
if((a = (int*)malloc(n*sizeof(int))) == NULL)
{
printf("系統內存空間不足!");
exit(0);
}
for(i = 0;i < n; i++)
{
a[i] = i + 1;
}
for(i = 0;i < n; i++)
{
printf("%d ",a[i]);
}
printf("\n");
free(a);
}
例2:
定義有3行,4列整數類型的二維數組a,先逐行分別給數組元素賦數據1,2,…,12,然後顯示數組中的數值。要求分別把申請二維動態數組的過程和釋放二維動態數組的過程編寫成函數。
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
//函數返回動態申請的row行,col列的二維動態數組,內存不足時退出
int ** Make2DArray(int row,int col)
{
int **a,i;
//動態申請 row個int指針類型的內存空間,內存不足時退出
if((a = (int**)malloc(row*sizeof(int*))) == NULL)
{
printf("系統內存空間不足!");
exit(0);
}
for(i = 0;i < row; i++)
{
if((a[i] = (int*)malloc(col*sizeof(int))) == NULL)
{
//動態申請col個int類型的內存空間,內存不足時退出
printf("系統內存空間不足!");
exit(0);
}
}
return a;
}
//釋放二維 動態數組a的存儲空間,row爲數組行數
void Diliver2DArray(int**a,int row)
{
int i;
for(i = 0;i < row; i++)
free(a[i]);
free(a);
}
void main(void)
{
int i,j,c;
int row = 3,col = 4,**a;
a = Make2DArray(row,col);
c = 1;
for(i = 0;i < row; i++)
{
for(j = 0;j < col; j++)
{
a[i][j] = c;
c++;
}
}
for(i = 0;i < row; i++)
{
for(j = 0;j < col; j++)
{
printf("%d\t",a[i][j]);
}
printf("\n");
}
Diliver2DArray(a,row);
}
稀疏矩陣的壓宿存儲
用順序表存儲的三元組線性表稱作三元組順序表。三元組順序表是把三元組定義成順序表的數據元素。因此,可把三元組定義成順序表的數據元素:
typedef struct {
DataType list[MaxSize];
int size;
}SeqList;
//順序表操作實現
//1.初始化
void ListInitiate(SeqList*L)
{
L->size = 0;//定義初始數據元素個數
}
//2.求當前數據元素個數
int ListLength(SeqList L)
{
return L.size;//返回順序表L的當前數據元素個數
}
//3.插入數據元素
int ListInsert(SeqList*L,int i,DataType x)
{
/*
在順序表L的第i(0<=i<=size)個位置前插入數據元素值x
插入成功返回1,插入失敗返回0
*/
int j;
if(L->size >= MaxSize)
{
printf("順序表已滿無法插入!\n");
return 0;
}
else if(i < 0 || i > L->size)
{
printf("參數i不合法!\n");
return 0;
}
else
{
/*爲插入做準備*/
for(j=L->size;j > i; j--)
{
L->list[j] = L->list[j-1];
}
L->list[i] = x; /*插入元素x*/
L->size++; /*元素個數加1*/
return 1;
}
}
//4.刪除數據元素
int ListDelete(SeqList*L,int i,DataType*x)
{
/*
刪除順序表L中位置爲i(0<=i<=size-1)的數據元素並存放到x中
刪除成功返回1,刪除失敗返回0
*/
int j;
if(L->size <= 0)
{
printf("順序表已空無數據元素可刪!\n");
return 0;
}
else if(i < 0 || i > L->size - 1)
{
printf("參數i不合法\n");
return 0;
}
else
{
*x = L->list[i]; /* 保存刪除的元素到x中*/
for(j = i;j < L->size-1; j++)
{
L->list[j] = L->list[j+1];
}
L->size--; /*數據元素個數減1*/
return 1;
}
}
//5.取數據元素
int ListGet(SeqList L,int i,DataType* x)
{
/* 取順序表L中第i個數據元素存於x中,成功返回1,失敗返回0*/
if(i < 0 || i > L.size - 1)
{
printf("參數i不合法!\n");
return 0;
}
else
{
*x=L.list[i];
return 1;
}
}
#include <stdio.h>
#define MaxSize 1000
typedef int elemtype;
typedef struct
{
int i; //行號
int j; //列號
elemtype d; //元素值
} DataType;
typedef struct
{
int md; //行數
int nd; //列數
int td; //非零元素個數
} TriType;
#include "SeqList.h"
/*
a爲轉置前的三元組順序表,da是a的控制數據
三元組順序表a按先行序後列序的順序存放
*/
void Transition1(SeqList a,TriType da,SeqList *b,TriType*db)
{
int p;
db->md = da.nd;
db->nd = da.md;
db->td = da.td;
if(da.td != 0)
{
for(p = 0;p < da.td; p++)
{
b->list[p].i = a.list[p].j;
b->list[p].j = a.list[p].i;
b->list[p].d = a.list[p].d;
}
}
}
/*
a爲轉置前的三元組順序表,da是a的控制數據
三元組順序表a按先行序後列序的順序存放
b爲轉置後的三元組順序表,db是b的控制數據
*/
void Transition2(SeqList a,TriType da,SeqList*b,TriType*db)
{
int p,q,v;
db->md = da.nd;
db->nd = da.md;
db->td = da.td;
if(da.td == 0) return 0;
else
{
q = 0;
for(v = 1;v <= da.nd; v++)
{
for(p = 0;p < da.td; p++)
{
if(a.list[0].j == v)
{
//尋找原矩陣中列下標值最小的
b->list[q].i = a.list[p].j;
b->list[q].j = a.list[p].i;
b->list[q].d = a.list[p].d;
q++;
}
}
}
}
}
例3:
將圖A轉置爲圖B
#include <stdio.h>
#define MaxSize 1000
typedef int elemtype;
typedef struct
{
int i; //行號
int j; //列號
elemtype d; //元素值
} DataType;
typedef struct
{
int md; //行數
int nd; //列數
int td; //非零元素個數
} TriType;
#include "SeqList.h"
void Transition(SeqList a,TriType da,SeqList*b,TriType*db)
{
int p,q,v;
db->md = da.nd;
db->nd = da.md;
db->td = da.td;
if(da.td != 0)
{
q = 0;
for(v = 1;v <= da.nd; v++)
{
for(p = 0;p < da.td; p++)
{
if(a.list[p].j == v)
{
b->list[q].i = a.list[p].j;
b->list[q].j = a.list[p].i;
b->list[q].d = a.list[p].d;
q++;
}
}
}
}
}
void main(void)
{
SeqList listA,listB;
TriType myA = {6,7,6},myB;
DataType a[] = {
{1,3,11},{1,5,17},{2,2,25},{4,1,19},{5,4,37},{6,7,50}
};
int i;
ListInitiate(&listA); //順序表初始化
for(i = 0;i < myA.td; i++)
ListInsert(&listA,i,a[i]); //向順序表第i個位置插入元素
printf("轉置前-行數:%d\t列數:%d\t非零元數:%d\n",myA.md,myA.nd,myA.td);
printf("三元組元素依次爲:\n");
for(i = 0;i < myA.td; i++)
printf("%d\t%d\t%d\n",listA.list[i].i,listA.list[i].j,listA.list[i].d);
printf("\n\n");
Transition(listA,myA,&listB,&myB); //轉置
printf("轉置後-行數:%d\t列數:%d\t非零元數:%d\n",myB.md,myB.nd,myB.td);
printf("三元組元素依次爲:\n");
for(i = 0;i < myB.td; i++)
printf("%d\t%d\t%d\n",listB.list[i].i,listB.list[i].j,listB.list[i].d);
}