1. 程式人生 > >[資料結構&基操][C++]一個二維網狀資料結構及基本操作

[資料結構&基操][C++]一個二維網狀資料結構及基本操作

一是因為上學期學了資料結構,二是因為面對物件的程式設計學的不精,我便用資料結構做了一個資訊管理系統作為C艹大作業。

沒想到居然拿了優秀 ψ(`∇´)ψ (不管難否,反正是筆者五級分制中唯一的優秀)

 

先上資料結構圖

 

貼程式碼

結構體:

​typedef struct Grade {            //某個學生的成績資訊
	char TextName[12];
	int Weight;//權重
	int Chinese;
	int Math;
	int English;
	int Science;
	Grade* next;
}Grade, *GradePtr;

typedef struct Information {      //單個學生的資訊
	char Name[12];
	int ID;
	char sex[5];
	char birthday[12];
	char phone[15];
	GradePtr G;               //指向成績資訊
	Information* next;
}Information, *InformationPtr;​

基本操作:

//連結串列基本操作函式


//建立連結串列

int CreateList(InformationPtr &I) {	 
	I = (InformationPtr)malloc(sizeof(Information));
	if (!I) return ERROR;
	I->next = NULL;                  //I的next域用於儲存末尾指標
	return OK;
}


 //資料入連結串列(一個學生的資料)

int EnList(InformationPtr &I, char a[IAmount + GAmount * TextLimit][20]) {
//IAmount、GAmount、TextLimit為全域性變數。前兩者又檔案流讀取確定學生個數和考試個數,後者為自定義能儲存的考試數目的上限,陣列a為儲存從檔案中讀取資料的陣列(一次讀一個學生的個人資訊和成績資訊)。
	InformationPtr q;
	q = (InformationPtr)malloc(sizeof(Information));

	//資料輸入(對Information結構體)
	strcpy_s(q->Name, a[0]);    /*名字*/	//使用串複製
	q->ID = atoi(a[1]);         /*學號*/	//將字串陣列型式儲存的資料轉化為int型
	strcpy_s(q->sex, a[2]);     /*性別*/
	strcpy_s(q->birthday, a[3]);/*生日*/
	strcpy_s(q->phone, a[4]);   /*電話*/

	//指標操作(對Information結構體)
	InformationPtr Irear = I;
	while (Irear->next) {
		Irear = Irear->next;
	}
	Irear->next = q; q->next = NULL;


	GradePtr Ghead;
	Ghead = (GradePtr)malloc(sizeof(Grade));
	q->G = Ghead;
	Ghead->next = NULL;
	for (int i = 0; i<TextAmount; i++) {
		GradePtr p;
		p = (GradePtr)malloc(sizeof(Grade));

		//資料輸入(對Grade結構體)
		strcpy_s(p->TextName, a[IAmount + i * GAmount]);/*考試名*/
		p->Weight = atoi(a[IAmount + i * GAmount + 1]);/*權重*/
		p->Chinese = atoi(a[IAmount + i * GAmount + 2]);/*語文*/
		p->Math = atoi(a[IAmount + i * GAmount + 3]);/*數學*/
		p->English = atoi(a[IAmount + i * GAmount + 4]);/*英語*/
		p->Science = atoi(a[IAmount + i * GAmount + 5]);/*理綜*/
										
                //指標操作(對Grade結構體)
		GradePtr Grear = Ghead;
		while (Grear->next) {
			Grear = Grear->next;
		}
		Grear->next = p; p->next = NULL;
	}
	ListLength++;//結點個數增加(全域性變數)
	return OK;
}


//清空連結串列(注意該連結串列實際上含有兩個連結串列(Information在外,Grade在內),要先把內部連結串列free(釋放))

int ClearList(InformationPtr &I) { 
	ListLength = 0;
	InformationPtr q1 = 0, q2 = 0;
	GradePtr p1 = 0, p2 = 0;
	q1 = I->next;
	while (q1) {
		p1 = q1->G->next;
		while (p1) {
			p2 = p1->next;
			free(p1);
			p1 = p2;
		}
		q2 = q1->next;
		free(q1);
		q1 = q2;
	}
	I->next = NULL;
	return OK;
}


//刪除以I為頭節點的第n個結點(n=0指頭結點(不可刪除))(n需大於等於1)

int I_DeleteList(InformationPtr &I, int n) {	
        InformationPtr q1, q2;
	q1 = I; q2 = q1->next;
	int i = 1;
	while (q2) {
		if (i == n) {
			q1->next = q2->next;
			//釋放malloc分配的G空間
			GradePtr p1, p2;
			p1 = q2->G->next;
			while (p1) {
				p2 = p1->next;
				free(p1);
				p1 = p2;
			}
			free(q2);
			ListLength--;//結點數-1(全域性變數)
			return OK;
		}
		i++;
		q1 = q2;
		q2 = q2->next;
	}
	return ERROR;
}


//刪除所有Information結點的第n個Grade結點

int G_DeleteList(InformationPtr &I, int n) {
	InformationPtr q = I->next;
	GradePtr p1, p2; int t;
	for (int i = 0; i<ListLength; i++) {
		p1 = q->G; p2 = p1->next;
		t = 1;
		while (p2) {
			if (t == n) {
				p1->next = p2->next;
				free(p2);
				p2 = NULL; 
                                break;
                        //用break跳出while,以免p2=p2->next中 p2free後p2->next無意義
			}
			p1 = p2; p2 = p2->next;
			t++;
		}
		q = q->next;
	}
	TextAmount--;//考試數減一
	return OK;
}


//生成新的Information空間(學生),返回空間的地址

InformationPtr I_Increase(InformationPtr I) {	
InformationPtr q;
	q = (InformationPtr)malloc(sizeof(Information));
	cout << "請輸入新建學生資訊:\n";
	cout << "姓名:"; cin >> q->Name;
	cout << "學號:"; cin >> q->ID;
	cout << "性別:"; cin >> q->sex;
	cout << "生日:"; cin >> q->birthday;
	cout << "電話:"; cin >> q->phone;
	q->next = NULL;
	q->G = NULL;
	GradePtr Ghead;
	Ghead = (GradePtr)malloc(sizeof(Grade));
	Ghead->next = NULL;
	q->G = Ghead;
	if (ListLength == 0)return q;
	GradePtr k = I->next->G;
	for (int i = 0; i<TextAmount; i++) {
		GradePtr p;
		p = (GradePtr)malloc(sizeof(Grade));
		k = k->next;
		strcpy_s(p->TextName, k->TextName);
		p->Weight = k->Weight;
		cout << "請錄入" << q->Name << "同學的" << p->TextName << "成績:\n";
		cout << "語文:"; cin >> p->Chinese;
		cout << "數學:"; cin >> p->Math;
		cout << "英語:"; cin >> p->English;
		cout << "理綜:"; cin >> p->Science;
		GradePtr Grear = Ghead;
		while (Grear->next) {
			Grear = Grear->next;
		}
		Grear->next = p; p->next = NULL;
	}
	cout << "學生資訊新增完成"; system("pause");
	return q;
}

資料結構的難點主要在於指標操作,修改程式碼中的資料操作就可以實現自己想實現的功能了o(* ̄▽ ̄*)o