Tạo một danh sách list A chứa số ghế trong trong rạp chiều phim 1 đến n
#include #include #include #define TRUE 1 #define INVALID_CITY_CODE -1 // Khai báo kiểu cấu trúc City struct City { int code; char name[100]; float area; int population; }; // Định nghĩa cho kiểu "struct City" 1 tên mới ngắn gọn hơn, thay vì khai báo kiểu "struct City" thì ta chỉ cần dùng "City" typedef struct City City; // Khai báo kiểu cấu trúc LinkedList struct LinkedList{ City city; struct LinkedList *next; }; // Định nghĩa cho kiểu "struct LinkedList" 1 tên mới ngắn gọn hơn, thay vì khai báo kiểu "struct LinkedList" thì ta chỉ cần dùng "Node" typedef struct LinkedList *Node; // Hàm tạo mới 1 Node trong LinkedList Node createNode(City city){ Node temp; // Khai báo 1 Node temp = (Node)malloc(sizeof(struct LinkedList)); // Cấp phát vùng nhớ cho Node temp->next = NULL;// Cho next trỏ tới NULL temp->city = city; // Gán giá trị cho Node return temp; } // Thêm vào cuối Node addTail(Node head, City value){ Node temp,p;// Khai báo 2 Node tạm temp và p temp = createNode(value);//Gọi hàm createNode để khởi tạo Node temp có next trỏ tới NULL và giá trị là value if(head == NULL){ head = temp; //Nếu linked list đang trống thì Node temp là head luôn } else{ p = head;// Khởi tạo p trỏ tới head while(p->next != NULL){ p = p->next;//Duyệt danh sách liên kết đến cuối. Node cuối là Node có next = NULL } p->next = temp;//Gán next của thằng cuối = temp. Khi đó temp sẽ là thằng cuối(temp->next = NULL mà) } return head; } // Thêm vào đầu Node addHead(Node head, City value){ Node temp = createNode(value); // Khởi tạo Node temp với data = value if(head == NULL){ head = temp; // //Nếu linked list đang trống thì Node temp là head luôn }else{ temp->next = head; // Trỏ next của temp = head hiện tại head = temp; // Đổi head hiện tại = temp(Vì temp bây giờ là head mới mà) } return head; } // Thêm vào ở "chỉ số" (bắt đầu từ 0) bất kỳ, nếu muốn thêm theo "vị trí" (bắt đầu từ 1) thì giảm position đi 1 đơn vị Node addAt(Node head, City value, int position){ position = position - 1; // Thêm theo vị trí if(position == 0 || head == NULL){ head = addHead(head, value); // Nếu vị trí chèn là 0, tức là thêm vào đầu }else{ // Bắt đầu tìm vị trí cần chèn. Ta sẽ dùng k để đếm cho vị trí int k = 1; Node p = head; while(p != NULL && k != position){ p = p->next; ++k; } if(k != position){ // Nếu duyệt hết danh sách lk rồi mà vẫn chưa đến vị trí cần chèn, ta sẽ mặc định chèn cuối // Nếu bạn không muốn chèn, hãy thông báo vị trí chèn không hợp lệ head = addTail(head, value); // printf("Vi tri chen vuot qua vi tri cuoi cung!\n"); }else{ Node temp = createNode(value); temp->next = p->next; p->next = temp; } } return head; } Node delHead(Node head){ if(head == NULL){ printf("\nCha co gi de xoa het!"); }else{ head = head->next; } return head; } Node delTail(Node head){ if (head == NULL || head->next == NULL){ return delHead(head); } Node p = head; while(p->next->next != NULL){ p = p->next; } p->next = p->next->next; // Cho next bằng NULL return head; } // Xóa Node ở "chỉ số" (bắt đầu từ 0) bất kỳ Node delAt(Node head, int position){ if(position == 0 || head == NULL || head->next == NULL){ head = delHead(head); // Nếu vị trí xóa là 0, tức là thêm vào đầu }else{ // Bắt đầu tìm vị trí cần xóa. Ta sẽ dùng k để đếm cho vị trí int k = 1; Node p = head; while(p->next->next != NULL && k != position){ p = p->next; ++k; } if(k != position){ // Nếu duyệt hết danh sách lk rồi mà vẫn chưa đến vị trí cần chèn, ta sẽ mặc định xóa cuối // Nếu bạn không muốn xóa, hãy thông báo vị trí xóa không hợp lệ head = delTail(head); // printf("Vi tri xoa vuot qua vi tri cuoi cung!\n"); }else{ p->next = p->next->next; } } return head; } void traverser(Node head){ printf("Danh sach hien tai:\n"); printf("------------------------------------------------------------------------------------------------------------\n"); printf("%10s%50s%20s%20s\n", "Ma Tinh/TP", "Tinh thanh", "Dien tich", "Dan so"); for(Node p = head; p != NULL; p = p->next){ printf("%10d%50s%20f%20d\n", p->city.code, p->city.name, p->city.area, p->city.population); } printf("------------------------------------------------------------------------------------------------------------\n"); } // Hàm khởi tạo Node đầu tiên của LinkedList Node initHead(){ Node head; head = NULL; return head; } // Hàm tách các thành phần của 1 dòng trong file City handleLineData(char *line){ City city; city.code = INVALID_CITY_CODE; // Khởi tạo giá trị không hợp lệ. Về sau ta có thể kiểm tra. const char delimiter[] = "\t"; char *tmp; tmp = strtok(line, delimiter); if (tmp == NULL) { printf("Du lieu khong dung dinh dang: %s", line); exit(EXIT_FAILURE); } city.code = atoi(tmp); int index = 0; for (;;index++) { tmp = strtok(NULL, delimiter); if (tmp == NULL) break; if (index == 0){ strcpy(city.name, tmp); }else if (index == 1){ city.area = (float)atof(tmp); }else if (index == 2){ city.population = atoi(tmp); }else { printf("Du lieu khong dung dinh dang: %s", line); exit(EXIT_FAILURE); } } return city; } // Hàm đọc dữ liệu từ tập tin Node readData(Node head, const char* fileName){ FILE* file = fopen(fileName, "r"); if(!file){ printf("Co loi khi mo file : %s\n", fileName); exit(EXIT_FAILURE); } char line[500]; while (fgets(line, sizeof(line), file)) { City city = handleLineData(line); if (city.code != INVALID_CITY_CODE) { head = addTail(head, city); } } fclose(file); return head; } City createCity(){ City newCity; char *p; printf("Nhap code: "); scanf("%d", &newCity.code); printf("Nhap ten: "); getchar(); fgets(newCity.name, 100, stdin); // Xóa \n ở cuối chuỗi vừa nhập nếu có if ((p=strchr(newCity.name, '\n')) != NULL){ *p = '\0'; } printf("Nhap dien tich: "); scanf("%f", &newCity.area); printf("Nhap dan so: "); scanf("%d", &newCity.population); return newCity; } Node addNode(Node head){ City newCity; char option; int position; while (TRUE) { printf("========== Nhap du lieu can them ===============\n"); printf("Nhap vi tri muon them: "); scanf("%d", &position); newCity = createCity(); head = addAt(head, newCity, position); printf("Them thanh cong? Them tiep (Y/n)? "); getchar(); // Bỏ qua '\n' trong bộ đệm scanf("%c", &option); if (option == 'N' || option == 'n'){ break; } } return head; } // Hàm tìm chỉ số của Node có dữ liệu thành phố mà mã code của nó trùng với giá trị cần tìm int findIndexByCode(Node head, int code){ int index = -1; for(Node p = head; p != NULL; p = p->next){ index++; if (p->city.code == code){ return index; } } return -1; // Không tìm thấy } void editNode(Node head){ int code; char option; City newCity; while (TRUE) { printf("========== Chon Node muon sua ===============\n"); printf("Nhap ma tinh/thanh pho can sua: "); scanf("%d", &code); int found = 0; for(Node p = head; p != NULL; p = p->next){ if (p->city.code == code){ found = 1; newCity = createCity(); p->city = newCity; break; } } if (found) { printf("Sua thanh cong! Sua tiep (Y/n)? "); }else { printf("Khong tim thay du lieu! Sua tiep (Y/n)? "); } getchar(); // Bỏ qua '\n' trong bộ đệm scanf("%c", &option); if (option == 'N' || option == 'n'){ break; } } } Node removeNode(Node head){ int code; char option; while (TRUE) { printf("========== Chon Node muon xoa ===============\n"); printf("Nhap ma tinh/thanh pho can xoa: "); scanf("%d", &code); int position = findIndexByCode(head, code); if (position < 0){ printf("Khong tim thay du lieu can xoa! Xoa tiep (Y/n)? "); }else { head = delAt(head, position); printf("Xoa thanh cong? Xoa tiep (Y/n)? "); } getchar(); // Bỏ qua '\n' trong bộ đệm scanf("%c", &option); if (option == 'N' || option == 'n'){ break; } } return head; } // Hàm tính tổng diện tích các thành phố trong DSLK float sumArea(Node head){ float sum = 0; for(Node p = head; p != NULL; p = p->next){ sum += p->city.area; } return sum; } // Hàm tìm chỉ số của Node có diện tích lớn nhất (giả sử chỉ có 1) // Nếu dữ liệu có nhiều hơn 1, chúng ta tìm max rồi duyệt lại 1 lần nữa để tìm ra các Node có giá trị = max đó int indexOfMaxArea(Node head){ int maxIndex = 0, index = 0; int maxArea = head->city.area; for(Node p = head; p != NULL; p = p->next){ if (p->city.area > maxArea){ maxArea = p->city.area; maxIndex = index; } index++; } return maxIndex; } // Hàm tìm Node có dân số lớn nhất City maxByPopulation(Node head){ City city = head->city; for(Node p = head; p != NULL; p = p->next){ if (p->city.population > city.population){ city = p->city; } } return city; } void swapCityData(City *a, City *b){ City tmp = *a; *a = *b; *b = tmp; } // Hàm sắp xếp // Nếu sort theo code, thì byCode = 1, byArea = 0 // Nếu sort theo area, thì byCode = 0, byArea = 1 // Nếu sắp xếp tăng dần thì desc = 0, giảm dần thì desc = 1 void sortCities(Node head, int byCode, int byArea, int desc){ for(Node p = head; p != NULL; p = p->next){ for(Node q = p->next; q != NULL; q = q->next){ if (desc){ if (byCode && p->city.code < q->city.code){ swapCityData(&p->city, &q->city); }else if (byArea && p->city.area < q->city.area){ swapCityData(&p->city, &q->city); } }else { if (byCode && p->city.code > q->city.code){ swapCityData(&p->city, &q->city); }else if (byArea && p->city.area > q->city.area){ swapCityData(&p->city, &q->city); } } } } } void printMenu(){ printf("================== MENU ====================\n"); printf("1. Duyet danh sach\n"); printf("2. Them du lieu (them Node)\n"); printf("3. Sua du lieu (sua Node)\n"); printf("4. Xoa du lieu (xoa Node)\n"); printf("5. Tinh tong dien tich\n"); printf("6. Tim dia chi cua Node co dien tich lon nhat\n"); printf("7. Tim tinh co dan so lon nhat\n"); printf("8. Sap xep danh sach theo ma tinh\n"); printf("9. Sap xep danh sach theo dien tich\n"); printf("10. Thoat chuong trinh\n"); printf("============================================\n"); } int main(){ Node head = initHead(); head = readData(head, "DS_CAC_TINH.txt"); traverser(head); int option; City result; while (TRUE) { printMenu(); printf("Nhap lua chon cua ban (1-10): "); scanf("%d", &option); switch(option) { case 1: traverser(head); break; case 2: head = addNode(head); break; case 3: editNode(head); break; case 4: head = removeNode(head); break; case 5: printf("Tong dien tich: %f\n", sumArea(head)); break; case 6: printf("Tinh co dien tich lon nhat o vi tri: %d\n", indexOfMaxArea(head) + 1); // vị trí = chỉ số + 1 break; case 7: result = maxByPopulation(head); printf("%s la noi co dien tich lon nhat voi %d nguoi!\n", result.name, result.population); break; case 8: sortCities(head, 1, 0, 0); traverser(head); break; case 9: sortCities(head, 0, 1, 0); traverser(head); break; case 10: printf("Ket thuc chuong trinh!...\n"); exit(EXIT_SUCCESS); default: printf("Lua chon khong dung, vui long nhap lai!\n"); break; } } } |