1. Trang chủ
  2. » Công Nghệ Thông Tin

Kỹ thuật lập trình c c chương cấu trúc dữ liệu

21 124 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Cấu trúc liệu EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Mở đầu: mảng động Mảng C có số phần tử cố định từ khai báo Mảng động mảng có số phần tử thay đổi: chất trỏ biến cho biết số phần tử    int n = 5; int* arr = (int*)malloc(n*sizeof(int)); Bài toán chèn phần tử vào mảng động:   pos = 2; val = 25; arr1 = (int*)malloc((n+1)*sizeof(int)); memcpy(arr1, arr, pos*sizeof(int)); memcpy(arr1+pos+1, arr+pos, (n-pos)*sizeof(int)); arr1[pos] = val; 10 20 30 40 50 free(arr); 25 arr = arr1; Tương tự xoá phần tử  10 EE3490: thuật lập 30 trình – HK1 20 Kỹ25 402011/2012 50 Đào Trung Kiên – ĐH Bách khoa Hà Nội Khái niệm Ví dụ cho thấy mảng động hiệu việc thêm/bớt phần tử cần di chuyển vùng nhớ, mảng có nhiều phần tử  cần cấu trúc liệu linh hoạt Các cấu trúc liệu phổ biến, ứng dụng tuỳ toán:           Ngăn xếp (stack) Hàng đợi (queue) Danh sách liên kết (linked list) Mảng động (vector, dynamic array) Ánh xạ (map), từ điển (dictionary), bảng băm (hash table) Tập hợp (set) Cây (tree) Đồ thị (graph) EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Danh sách liên kết (DSLK) Là tập hợp phần tử móc nối với trỏ:   Một trỏ trỏ đến phần tử (hoặc NULL chưa có phần tử nào)  Mỗi phần tử bao gồm thành phần: liệu, trỏ next tới phần tử  Con trỏ next phần tử cuối trỏ đến NULL list data next data next data next EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Khai báo DSLK Ví dụ với liệu kiểu int:   struct SELEM; typedef struct SELEM ELEM, *PELEM, *LLIST; struct SELEM { int data; PELEM next; }; Thư viện DSLK:   llist.h  llist.c EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Thao tác với DSLK Các hàm cần viết:   LLIST llInit();  LLIST llInsertHead(LLIST l, int data); LLIST llInsertTail(LLIST l, int data); LLIST llInsertAfter(LLIST l, PELEM a, int data);          LLIST LLIST LLIST LLIST llDeleteHead(LLIST l); llDeleteTail(LLIST l); llDeleteAfter(LLIST l, PELEM a); llDeleteAll(LLIST l); PELEM llSeek(LLIST l, int i); void llForEach(LLIST l, LLCALLBACK func); int llLength(LLIST l); EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Khởi tạo DSLK LLIST llInit() { return NULL; } Khởi tạo DSLK với NULL  chưa có phần tử  EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Thêm phần tử vào đầu DSLK LLIST llInsertHead(LLIST l, int data) { PELEM e = (PELEM)malloc(sizeof(ELEM)); e->data = data; e->next = l; return l = (LLIST)e; } list data data next data next next data next EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Thêm phần tử vào cuối DSLK LLIST llInsertTail(LLIST l, int data) { PELEM p; PELEM e = (PELEM)malloc(sizeof(ELEM)); e->data = data; e->next = NULL; list data next if (!l) return (LLIST)e; data data next data next for (p=l; p->next; p = p->next) ; p->next = e; next return l; } EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Thêm phần tử vào sau phần tử DSLK LLIST llInsertAfter(LLIST l, PELEM a, int data) { PELEM e; if (!a) return l; e = (PELEM)malloc(sizeof(ELEM)); e->data = data; e->next = a->next; list a->next = e; data return l; a data next } data next next data next 10 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Xoá phần tử đầu DSLK LLIST llDeleteHead(LLIST l) { PELEM p; if (!l) return NULL; p = l->next; free(l); return (LLIST)p; list data next data } next data next 11 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Xoá phần tử cuối DSLK LLIST llDeleteTail(LLIST l) { PELEM p; if (!l) return NULL; if (!l->next) { free(l); return NULL; } list data next data next data for (p=l; p->next->next; p = p->next) ; free(p->next); p->next = NULL; return l; }12 next EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Xoá phần tử sau phần tử DSLK LLIST llDeleteAfter(LLIST l, PELEM a) { PELEM p; if (!a || !a->next) return l; p = a->next; a->next = p->next; free(p); return l; a list data next data } next data next 13 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Duyệt DSLK  Tìm đến phần tử thứ i DSLK PELEM llSeek(LLIST l, int i) { for (; i>0 && l; i ) l = l->next; return (PELEM)l; }  Gọi hàm với phần tử DSLK typedef void (*LLCALLBACK)(int, void*); void llForEach(LLIST l, LLCALLBACK func, void* user) { for (; l; l=l->next) func(l->data, user); } 14 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Các hàm khác với DSLK  Đếm số phần tử int llLength(LLIST l) { int c; for (c=0; l; c++) l = l->next; return c; }  Xoá tất phần tử LLIST llDeleteAll(LLIST l) { PELEM p; for (; l; l=p) { p = l->next; free(l); } return NULL; } 15 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Ví dụ sử dụng DSLK for (i=0; inext) printf("%d ", l->data); printf("\n"); } void listSum(int data,void* user) { int* pS = (int*)user; *pS += data; } int main() { LLIST l; PELEM p; int i, s; p = llSeek(l, 1); l = llDeleteAfter(l, p); l = llDeleteHead(l); l = llDeleteTail(l); printList(l); s = 0; llForEach(l, listSum, (void*)&s); printf("Tong gia tri: %d\n", s); l = llDeleteAll(l); printList(l); return 0; l = llInit(); } 16 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Đặc điểm DSLK  Ưu/nhược điểm so với mảng động: + + – –  Linh hoạt: thêm/bớt phần tử dễ dàng, xếp thay đổi thứ tự phần tử mà không cần di chuyển nhớ Không cần cấp phát vùng nhớ lớn liên tục Cần thêm nhớ phụ cho biến trỏ Không truy cập tới phần tử thứ i mảng, mà phải duyệt từ đầu tới Ngồi dạng bản, có nhiều biến thể DSLK: DSLK kép, DSLK có thứ tự, hàng đợi, ngăn xếp, DSLK vịng,… có nhiều cách cài đặt khác tuỳ thuộc vào tốn cụ thể 17 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Ngăn xếp (stack)  Ngăn xếp trường hợp riêng DSLK, có hai thao tác: push: thêm phần tử vào đầu danh sách Push  pop: lấy giá trị đồng thời xoá phần tử đầu danh sách  thuộc loại danh sách LIFO (last in, first out)   Pop Ứng dụng:     18 Tính tốn biểu thức (ký pháp Ba Lan ngược) Thực việc gọi hàm ngơn ngữ lập trình Giải đệ quy Dữ liệu undo EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Hàng đợi (queue)  Hàng đợi trường hợp riêng DSLK, có hai thao tác: Enqueue enqueue: thêm phần tử vào cuối danh sách  dequeue: lấy giá trị đồng thời xoá phần tử đầu danh sách  thuộc loại danh sách FIFO (first in, first out)    Để lập trình hàng đợi, thường dùng hai trỏ: tới đầu danh sách để thêm, tới cuối danh sách để lấy phần tử Ứng dụng:    19 Dequeue Truyền thông tin, liệu Bộ nhớ đệm đọc/ghi liệu Cài đặt dịch vụ (mơ hình client/server) EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội DSLK kép (doubly linked list)   Trong DSLK thơng thường, phần tử có trỏ next tới phần tử  gọi DSLK đơn, duyệt DS chiều DSLK kép: phần tử có thêm trỏ prev tới phần tử trước  duyệt hai chiều prev list data prev next data prev next data next 20 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội Bài tập 21 Khai báo DSLK kép viết hàm: thêm/xoá phần tử đầu Viết hàm Pop(), Push() ngăn xếp Enqueue(), Dequeue() hàng đợi dựa DSLK nhận xét hàm khơng hiệu Tính giá trị trung bình giá trị DSLK hai cách: duyệt danh sách, sử dụng hàm llForEach() Viết hàm llConvert(int* arr, int count) chuyển liệu từ mảng sang DSLK, không dùng hàm viết Viết hàm llReverse(LLIST l) đảo ngược thứ tự DSLK, không cấp phát thêm phần tử Như dùng phương pháp đệ quy Có hai DSLK l1 l2, viết hàm llInsertListAfter(l1, l2, p) để chèn l2 vào l1 sau vị trí phần tử p EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách khoa Hà Nội ...  c? ??n c? ??u tr? ?c liệu linh hoạt C? ?c cấu tr? ?c liệu phổ biến, ứng dụng tuỳ toán:           Ngăn xếp (stack) Hàng đợi (queue) Danh sách liên kết (linked list) Mảng động (vector, dynamic... danh sách để thêm, tới cuối danh sách để lấy phần tử Ứng dụng:    19 Dequeue Truyền thông tin, liệu Bộ nhớ đệm đ? ?c/ ghi liệu C? ?i đặt dịch vụ (mơ hình client/server) EE3490: Kỹ thuật lập trình. .. (*LLCALLBACK)(int, void*); void llForEach(LLIST l, LLCALLBACK func, void* user) { for (; l; l=l->next) func(l->data, user); } 14 EE3490: Kỹ thuật lập trình – HK1 2011/2012 Đào Trung Kiên – ĐH Bách

Ngày đăng: 04/12/2015, 07:32

Xem thêm: Kỹ thuật lập trình c c chương cấu trúc dữ liệu

TỪ KHÓA LIÊN QUAN