Kỹ thuật lập trình C
1 Kỹ thuậ t lậ p trì nh CHƯƠNG i ĐạI CƯƠNG Về LậP TRìNH I Khái niệm thuật toán: I.1 Khái niệ m: Thuậ t toá n tậ p hợp cá c quy tắ c có logic nhằ m giả i lớp bà i toá n nà o để kế t xá c định I.2 Các tí nh chất đặc trưng thuật to¸n : I.2.1 TÝ nh tỉng qu¸t : Th t toá n lậ p không phả i để giả i bà i toá n cụ thể mà mà phả i giả i lớp cá c bà i toá n có ng tương tự I.2.2 Tí nh giới hạn : Thuậ t toá n giả i bà i toá n phả i thực hiệ n qua số giới hạ n cá c thao tá c để đạ t đế n kÕ t qu¶ I.2.3 TÝ nh nhÊt : Toà n trì nh biế n đổi, trậ t tự thực hiệ n phả i xá c định nhấ t Như vậ y dùng thuậ t toá n liệ u ban đầ u phả i cho kế t I.3 Phân loại: Theo cấ u trúc, ta phâ n nh ba loạ i thuậ t toá n bả n sau : - Thuậ t toá n không phâ n nhá nh - Thuậ t toá n có phâ n nhá nh - Thuậ t toá n theo chu trì nh có bước lặ p xá c định có bước lặ p không xá c định II Mô tả thuật toán b»ng lu ®å : II.1 Lu ®å : Lu ®å ng đồ thị dùng để mô tả trì nh tí nh toá n cá ch cã hƯ thèng Ngêi ta thêng thĨ hiƯ n th t toá n bằ ng lưu đồ II.2 Các ký hiệ u trê n lưu đồ : Tê n khối Khối mở đầ u hoặ c kế t thúc Khối vµ o Ký hiƯ u ý nghÜ a Dïng mở đầ u hoặ c kế t thúc chương trì nh Đưa số liệ u o hoặ c in kế t Kỹ thuậ t lậ p trì nh Biể u diễ n cá c công thức tí nh toá n thay đổi giá trị cá c biế n Dùng để phâ n nhá nh chương trì nh Khối tí nh toá n Khối điề u kiệ n Dùng để gọi chương trì nh Chỉ hướng truyề n thông tin, liê n hệ cá c khối Chương trì nh Mũi tê n II.3 Một sè vÝ dơ biĨ u diƠ n tht to¸n b»ng lưu đồ II.3.1 Thuật toán không phân nhánh: Ví dụ 1: TÝ nh A = x2 + y2 Begin Nhaäp (x,y) A = x2 + y2 Xuaát (A) End VÝ dô : TÝ nh S = Ax + By + C x +y 2 ; biÕ t A,B,C,x,y Begin Nhaä p (A, B, C, x,y) S = (Ax + By + C) / SQRT (x*x + y*y) Xuaát S End Kü thuË t lË p tr× nh II.3.2 Thuật toán có phân nhánh: Ví dụ 1: Tì m giá trị max ba số thực a,b,c Begin Nhập (a, b, c) S a>b Max = b Đ Max = a S Max < c Ñ Max = c Xuaỏt (Max) End Ví dụ 2: Giả i phương trì nh bậ c nhấ t Ax+B =0 với cá c nghiƯ m thùc Begin Nhập (a, b) a=0 S Xuất (-b/a) Đ b=0 S Đ Xuất (‘PTVĐ’) End Xuất (‘PTVN’) Kü thuË t lË p tr× nh VÝ dụ : Giả i phương trì nh bậ c hai Ax2+Bx+C =0 víi c¸ c nghiƯ m thùc Begin Nhập (a, b, c) Đ a=0 PTB1 (b, c) S Delta = b*b - 4*a*c Đ Delta < Xuất (‘PTVN’) S Đ Delta = Xuất (-b / (2*a)) S Xuaát (‘X1= ’,(-b + SQRT(Delta)) / (2*a)) Xuaát (‘X2= ’,(-b - SQRT(Delta)) / (2*a)) End II.3.3 ThuËt to¸n cã chu trì nh: Thuậ t toá n có chu trì nh với cá c bước lặ p xá c định thường thể hiệ n bằ ng lưu đồ sau : i = giá trị ban đầu Lệ nh S; Tă ng i Đ i left; p->left = root; } return p; } ! PhÐp xoay ph¶ i (Rotate_Right): xoay phả i câ y nhị phâ n tì m kiế m có nút gốc root, yê u cầ u root phả i có nút bê n trá i (gọi nút p) Sau xoay phả i nút p trở nh nút gốc, nút gốc cũ trở nh nút bê n phả i cđa nót gèc míi PhÐp xoay ph¶ i tr¶ vỊ trá chØ nót gèc míi NODEPTR Rotate_Right(NODEPTR root) { NODEPTR p; if(root == NULL) printf("Khong the xoay phai vi cay bi rong."); else if(root->left == NULL) printf("Khong the xoay phai vi khong co nut ben trai."); else { p = root->left; root->left = p->right; p->right = root; } return p; } Kü thuË t lË p tr× nh 124 !Thª m nót (Insert): thª m nót cã khóa x, nội dung a o câ y AVL: - Thê m nút theo giả i thuậ t thê m nút o câ y nhị phâ n tì m kiế m - Câ n bằ ng lạ i câ y bằ ng cá ch xoay đơn hay xoay kÐp void Insert(NODEPTR &pavltree, int x, int a) { NODEPTR fp, p, q, // fp lµ nót cha cđa p, q lµ cđa p fya, ya, /* ya nút trước gầ n nhấ t mấ t câ n bằ ng fya nút cha ya */ s; // s lµ nót cđa ya theo híng mÊ t c© n b» ng int imbal; /* imbal = nÕ u bÞ lƯ ch vỊ nhá nh trá i = -1 nế u bị lệ ch nhá nh phả i */ // Khởi động cá c giá trị fp = NULL; p = pavltree; fya = NULL; ya = p; // tim nut fp, ya va fya, nut moi them vao la nut la cua nut fp while(p != NULL) { if(x == p->info) // bi trung noi dung return; if (x < p->info) q = p->left; else q = p->right; if(q != NULL) if(q->bf != 0) // truong hop chi so can bang cua q la hay -1 { fya = p; ya = q; } fp = p; p = q; } // Them nut moi (nut la) la cua nut fp q = New_Node(); // cÊ p ph¸ t vïng nhí q->key =x; q->info = a; q->bf = 0; q->left = NULL; Kü thuË t lË p tr× nh 125 q->right = NULL; if(x < fp->info) fp->left = q; else fp->right = q; /* Hieu chinh chi so can bang cua tat ca cac nut giua ya va q, neu bi lech ve phia trai thi chi so can bang cua tat ca cac nut giua ya va q deu la 1, neu bi lech ve phia phai thi chi so can bang cua tat ca cac nut giua ya va q deu la -1 */ if(x < ya->info) p = ya->left; else p = ya->right; s = p; // s la nut ya while(p != q) { if(x < p->info) { p->bf = 1; p = p->left; } else { p->bf = -1; p = p->right; } } // xac dinh huong lech if(x < ya->info) imbal = 1; else imbal = -1; if(ya->bf == 0) { ya->bf = imbal; return; } if(ya->bf != imbal) { Kü thuË t lË p tr× nh ya->bf = 0; return; } if(s->bf == imbal) // Truong hop xoay don { if(imbal == 1) // xoay phai p = Rotate_Right(ya); else // xoay trai p = Rotate_Left(ya); ya->bf = 0; s->bf = 0; } else // Truong hop xoay kep { if(imbal == 1) // xoay kep trai-phai { ya->left = Rotate_Left(s); p = Rotate_Right(ya); } else // xoay kep phai-trai { ya->right = Rotate_Right(s); p = Rotate_Left(ya); } if(p->bf == 0) // truong hop p la nut moi them vao { ya->bf = 0; s->bf = 0; } else if(p->bf == imbal) { ya->bf = -imbal; s->bf = 0; } else { ya->bf = 0; s->bf = imbal; } 126 Kü thuË t lË p tr× nh p->bf = 0; } if(fya == NULL) pavltree = p; else if(ya == fya->right) fya->right = p; else fya->left = p; } * Để tạ o câ y nhị phâ n tì m kiÕ m c© n b» ng, ta sư dơng gi¶ i thuË t sau: void Create_AVLTree(NODEPTR &root) { int khoa, noidung; char so[10]; NODEPTR p; { printf("Nhap khoa :"); gets(so) ; khoa = atoi(so); if (khoa !=0) { printf("Nhap noi dung :"); gets(so) ; noidung = atoi(so); if (root==NULL) { p = New_Node(); p->key = khoa; p->info = noidung; p->bf = ; p->left = NULL; p->right = NULL; root =p; } else Insert(root,khoa,noidung); } } while (khoa!=0); // khãa =0 th× dõng nhË p } Ghi chó : Để tạ o câ y nhị phâ n biÕ n tree qu¶ n lý, ta gäi: Create_AVLTree(tree); 127 Kü thuË t lË p tr× nh 128 III.2.2 CËp nhật cây: Tì m kiế m (Search): Tì m nút có khóa bằ ng x trê n câ y nhị phâ n AVL có gốc root Nế u tì m thấ y x câ y trả địa nút có trị bằ ng x trongcâ y, nế u trả trị NULL Do AVL câ y nhị phâ n BST nê n ta tì m kiế m nhanh bằ ng phương phá p tì m kiế m nhị phâ n, tí nh chấ t lúc nà y câ y câ n bằ ng nê n thời gian tì m kiế m nhanh rấ t nhiÒ u NODEPTR search(NODEPTR root, int x) { NODEPTR p; p = root; while(p != NULL && x!=p->key) if(x < p->key) p = p->left; else p = p->right; return(p); } Xãa nót: Remove(root, x): - Néi dung: xãa nót có khóa x trê n câ y AVL với địa đầ u root cho sau xóa câ y vẫ n AVL - Giả i thuậ t: Nế u root == NULL Thôngbá o ("Không thể xóa đ ược nút x trê n câ y") NÕ u root != NULL th× NÕ u x< root->info : + Gọi đệ qui để xóa nút x nhá nh bê n trá i root : Remove(root->left, x) + Gọi balance_left để câ n bằ ng lạ i câ y nút gốc root nế u nhá nh câ y bê n trá i bị giả m độ cao Nế u x > root->info : + Gäi ®Ư qui ®Ĩ xãa nót x ë nhá nh bê n phả i root : Remove(root->right, x) + Gọi balance_right để câ n bằ ng lạ i câ y nút gốc root nế u nhá nh câ y bê n phả i bị giả m ®é cao NÕ u x==root->info th× : Xãa nót root phép toá n xóa trê n câ y nhị phâ n BST - Chương trì nh : tự cà i đặ t Kỹ thuậ t lậ p trì nh 129 III.2.3 Các phép duyệ t cây: Do câ y AVL câ y nhị phâ n nê n ta p dụng lạ i cá c phương phá p duyệ t Preorder, Inorder Postorder o c© y AVL a Du t c©y theo thø tù NLR (Preorder): void Preorder (NODEPTR root) { if(root != NULL) { printf("%d ", root->info); Preorder(root->left); Preorder (root->right); } } b Du t c©y theo thø tù LNR (Inorder): void Inorder(NODEPTR root) { if(root != NULL) { Inorder(root->left); printf("%d ", root->info); Inorder(root->right); } } c Du t c©y theo thø tù LRN (Posorder): void Posorder(NODEPTR root) { if(root != NULL) { Posorder(root->left); Posorder(root->right); printf("%d ", root->info); } } 130 Kü thuậ t lậ p trì nh Bà i tậ p: Viế t lạ i cá c chương trì nh duyệ t câ y nhị phâ n theo phương phá p không đệ qui Viế t chương trì nh tạ o menu thực hiệ n cá c mục sau: a Tạ o câ y nhị phâ n tì m kiế m với nội dung số nguyê n (không trùng nhau) b Liệ t kê câ y nhị phâ n mà n hì nh theo thứ tự NLR c Đế m tổng số nút, số nút , số nút trung gian câ y d Tí nh độ cao câ y e Loạ i bỏ nút có nội dung x câ y nhị phâ n BST f Thê m nút có nội dung x o câ y nhị phâ n BST cho sau thê m câ y vẫ n BST Cho câ y nhị phâ n tree, h y viế t chương trì nh để chép nh câ y tree2, với khóa, nội dung, liê n kế t giống câ y tree Viế t cá c hà m kiể m tra xem câ y nhị phâ n: a Có phả i câ y nhị phâ n không b Có phả i câ y nhị phâ n đầ y không Viế t hà m kiể m tra nút x y có trê n câ y hay không, nế u có x lẫ n y trê n câ y xá c định nót gèc cđa c© y nhá nhÊ t cã chứa x y Cho câ y biể u thøc, h∙ y viÕ t hµ m Calculate (NODEPTR root) để tí nh giá trị câ y biể u thức đó, biế t rằ ng cá c toá n tử đ ược dùng biể u thức : + - * / ^ % ! VÏ lạ i hì nh ả nh câ y nhị phâ n tì m kiế m, câ y nhị phâ n tì m kiế m câ n bằ ng nế u cá c nút thê m o câ y theo thø tù nh sau: 20 11 30 18 NhË p vµ o biÓ u thøc sè häc, chuyÓ n biÓ u thøc nh câ y nhị phâ n, nút gốc toá n tử, nút cá c toá n hạ ng, biế t rằ ng cá c toá n tử dùng biể u thức : + - * / ^ % ! 131 Kü thuË t lậ p trì nh MụC LụC CHƯƠNG i ĐạI CƯƠNG Về LậP TRìNH - I Kh¸i niƯm tht to¸n - I.1 Kh¸ i niƯ m - I.2 Cá c tí nh chấ t đặc trưng thuË t to¸ n - I.3 Phâ n loạ i - II Mô tả thuật toán lưu đồ II.1 Lu ®å II.2 Cá c ký hiệ u trê n lưu ®å - II.3 Mét sè vÝ dơ biĨu diƠ n th t toá n bằ ng lưu đồ III CáC NGôN NGữ LậP TRìNH & CHươNG TRìNH DịCH III.1 Ngôn ngữ lậ p trì nh III.2 Chương trì nh dịch CH¬NG LàM QUEN VớI NGôN NGữ C - * Giới thiệu ngôn ngữ C - I CáC KHáI NIệM Cơ BảN I.1 Cấ u trúc bả n chương trì nh C I.2 Kiể u liệ u 13 I.3 BiÕ n - 14 I.4 H» ng - 18 I.5 PhÐp to¸ n 20 * Sù chuyÓ n kiÓ u - 29 * Mức độ ưu tiê n cá c phÐp to¸ n 29 I.6 Chuỗi - 30 II Các cấu trúc điều khiển C 33 II.1 CÊ u tróc t n tù (Sequence) 33 II.2 CÊ u tróc chän 34 II.2.1 LÖ nh if else 34 II.2.2 LÖ nh switch_case 35 II.3 CÊ u tróc lỈ p - 37 II.3.1 LÖ nh while - 37 II.3.2 LÖ nh while 38 II.3.3 LÖ nh for 39 * Ph¸ t biĨ u break, continue, goto 40 Bµ i tË p 41 Kü thuË t lË p trì nh 132 III Hàm - Đệ quy 45 III.1 Hµ m 45 III.2 §Ư qui (Recursion) 52 IV Structure - 54 IV.1 §Þnh nghÜ a 55 IV.2 Khai b¸ o - 55 V FILE 56 V.1 File vă n bả n - 56 V.2 File nhị phâ n (file cã cÊ u tróc) 61 V.3 Phá t hiệ n lỗi truy xuấ t tậ p tin 66 Bµ i tË p 67 CHươNG CáC THUậT TOáN TRÊN CấU TRúC Dữ LIệU MảNG 69 I Mảng không xếp thuật toán tìm kiếm 69 mảng cha cã thø tù I.1 Mét sè kh¸ i niƯ m vỊ m¶ ng 69 I.2 Thuậ t toá n tì m kiếm trê n m¶ ng cha cã thø tù 71 II C¸c thuật toán xếp - 73 II.1 Sắ p xế p theo phương phá p Bubble_Sort 73 II.2 S¾ p xÕ p theo phương phá p Quick_Sort 75 III Tìm kiếm mảng đà có thứ tù - 79 III.1 T× m kiÕ m nhanh bằ ng phương phá p lặp - 79 III.2 Phép tì m kiế m nhị phâ n 80 III.3 PhÐp tì m kiế m nhị phâ n đệ qui - 81 Bµ i tË p 82 CHƯƠNG CON TRỏ (POINTER) 84 I §ÞNH NGHÜA - 84 I.1 Khai b¸ o 84 I.2 TruyÒ n địa cho hà m - 85 II Các phép toán biến trá - 85 II.1 To¸ n tử địa & - 85 II.2 To¸ n tö néi dung * - 85 II.3 PhÐp céng trõ biÕn trá víi mét sè nguyª n 86 II.4 PhÐp gá n phép so sá nh - 86 II.5 Sù chuyÓ n kiÓ u 86 II.6 Khai b¸ o trỏ hằ ng trỏ đến ®èi tỵng h» ng 87 III Sự tương quan trỏ m¶ng - 87 Kü thuË t lË p tr× nh 133 IV Con trỏ chuỗi 91 IV.1 Khai b¸ o - 91 IV.2 XÐt mét số ví dụ cá c hà m xử lý chuỗi - 91 IV.3 M¶ ng trá chØ đến chuỗi 93 Bµ i tË p 95 CHƯƠNG C¸C THT TO¸N TR£N CÊU TRóC - 96 DANH S¸CH LI£N KÕT (LINKED LIST) I Kh¸i niƯm 96 II C¸c phép toán danh sách liên kết - 97 II.1 T¹ o danh s¸ ch - 97 II.2 CË p nhË t danh s¸ch - 99 II.3 DuyÖ t danh s¸ ch 100 II.4 T× m kiÕ m - 100 II.5 S¾ p xÕ p 101 Bµ i tË p 102 CHươNG thuật toán cấu trúc câY - 104 I Phân loại c©y 104 I.1 Mét sè i niệ m bả n - 104 I.2 C¸ ch biĨ u diƠ n c©y - 106 I.3 BiĨ u diƠ n thø tự nút câ y - 106 II Cây nhị phân (Binary tree) 107 II.1 Định nghĩ a - 107 II.2 Cá c phép toá n câ y nhị phâ n 110 Tạ o câ y 110 CË p nhË t c© y - 112 C¸ c phÐp du t c©y 116 III nhị phân TìM KIếM cân (AVL) 117 III.1 §Þnh nghÜ a - 117 III.2 Cá c phép toá n câ y AVL 118 III.2.1 Thª m nót - 118 III.2.2 CË p nhË t c© y - 126 III.2.3 Cá c phép duyệt câ y 127 Bµ i tË p 129 TàI LIệU THAM KHảO Kỹ thuậ t lậ p trì nh Turbo C Đỗ Phúc, Nguyễ n Phi Khử, Tạ Minh Châ u, Nguyễ n Đì nh Tê 1992 Cấ u trúc liệ u ứng dụng cà i đặ t bằ ng C Nguyễ n Hồng Chương 1999 Những viê n ngọc Kỹ thuậ t lậ p trì nh JohnBentley ... ''2'': case ''3'': case ''4'': case ''5'': case ''6'': case ''7'': case ''8'': case ''9'': k=ch-''0''; break; case ''A'': case ''B'': case ''C'' : case ''D'': case ''E'': case ''F'':k=ch-''A''+10; break; case ''a'': case ''b'': case... trì nh c? ?? p cao c? ? c? ? u tr? ?c, gåm: c? ? u tr? ?c tuầ n tự, chọn, lặ p II.1 C? ??u tr? ?c (Sequence) : C? ? c lệ nh chương trì nh th? ?c hiệ n tuầ n tự từ lệ nh nà y đế n lệ nh c cho đế n hế t chương trì nh... Dữ liệu Chương trình nguồn Trình biê n dịch Chương trình đích Máy tính th? ?c Kết Hì nh I.1 Chương trì nh th? ?c thi theo chế dịch trì nh biê n dịch III.2.2 Trì nh thông dịch: trì nh dịch th? ?c thi