Danh sach lien ket - Tai lieu on thi cao hoc by girlbanks

VIEWS: 221 PAGES: 8

									                                                     -1-



                                      DANH SÁCH LIÊN KẾT

I. Danh sách liên kết đơn
1. Định nghĩa và khai báo
   Khai báo:
      {Định nghĩa kiểu con trỏ}
      TYPE Tro=^Nut;
            Nut=record
                    Info:Integer;
                    Next: Tro;
                 End;
      Var L:Tro;

      * Cấu trúc của một nút trong danh sách liên kết đơn.
                                                INFO       NEXT
            Trong đó :
            - Trường Info: Dùng lưu dữ liệu của nút, ở đây là giá trị kiểu nguyên Integer. Tùy bài toáncụ
              thể mà trường này có thể khác hoặc có thêm các trường khác cùng kết hợp để chứa dữ liệu.
            - Trường Next: Dùng để chứa địa chỉ của nút tiếp theo trong danh sách, có trường này các nút
              rời rạc mới có thể tạo thành danh sách.

      * Ví dụ danh sách liên kết đơn, nút đầu được trỏ bởi L (gọi tắt là danh sách liên kết
        đơn L).
                             L

                                 1        4      2            3        6        nil



2. Một số thuật toán

a. Duyệt danh sách
   Giả sử cho một danh sách được trỏ bởi nút L, hãy in giá trị chứa trong nút đó ra màn
   hình.
   - Bước 1: P:=L; {Bắt đầu duyệt từ vào nút đầu tiên trong danh sách}
                             L

                                 1        4      2            3        6        nil

                             P
      - Bước 2: Nếu P=Nil thì ngừng.
      - Bước 3: Nếu P <> nil thì in giá trị lưu trong nút được trỏ bởi P ra màn hình và
        gán P:=P^.Next.
                             L

                                 1        4      2            3        6        nil

                                      P
      - Bước 4: Quay lại Bước 2.

Ôn thi cao học – Danh sách liên kết
Trần Hoài Nhân
                                                       -2-


Giải thuật:
     Procedure InDanhSach(L:Tro);
     Var P:Tro;
     Begin
       P:=L;
       while (P<>nil) do
         begin
           writeln(P^.Info); p:=p^.next;
        end;
    End;


b. Thêm nút mới vào danh sách
   Thêm nút mới chứa giá trị X vào danh sách L.

         Thêm vào cuối danh sách
      Trường hợp 1: Danh sách rỗng, L= nil
      + New(L); info(L):=X;L^.Next:=nil;
      Trường hợp 2: Danh sách khác rỗng, L<> nil.
      + Duyệt đến nút cuối danh sách, được trỏ bởi P.
                               L

                                   1       4       2         3               6             nil

                                                                         P
      + Thực hiện các thao tác: New(Q); info(Q):=X; Q^.next:=nil;

                       L
                           1           4       2        3            6               nil
                                                                 P
                                                                                       7         nil

                                                                                 Q
      + P^.next:=Q;
                       L
                           1           4       2        3            6
                                                                 P
                                                                                       7         nil

                                                                                 Q
Giải thuật:
      Procedure ThemNut(var L:Tro; X:integer);
      Var p:tro;
        Begin
                 {trường hợp danh sách rỗng, L=nil}
                  if L=nil then
                    begin
                      new(L); L^.info:=X; L^.next:=nil;
                      exit; {thoát chương trình}
                    end;

Ôn thi cao học – Danh sách liên kết
Trần Hoài Nhân
                                                          -3-


                 {Trường hợp danh sách khác rỗng}
                  //Duyệt đến phần tử cuối, P^.next=nil
                  P:=L:
                  while (P^.next<>nil) do P:=P^.next;
                 //thay đổi múi nối
           New(Q); info(Q):=X; Q^.next:=nil; P^.next:=Q;
       End;

            Thêm vào đầu danh sách
                       L
                           1              4       2             3   6               7          nil


      + Thực hiện các thao tác: New(Q); info(Q):=X; Q^.Next:=L; L:=Q; Các hình sau mô
      ta các bước thực hiện:
      Trường hợp 1: Danh sách rỗng, L= nil
                       L                              L                     L
                 7          nil                   7       nil                   7       nil
          Q                                   Q                         Q



      Trường hợp 2: Danh sách khác rỗng
                                      L
                                          4       2         3       6               7         nil

                                1
                        Q


                                          4       2         3       6               7         nil
                            L
                                1
                        Q


Giải thuật:
      Procedure ThemNut(var L:tro; X:integer);
      Var Q:tro;
      Begin
        New(Q); info(Q):=X; Q^.Next:=L; L:=Q;
      End;

         Thêm vào trước một nút bất kỳ
      Thêm nút chứa giá trị X vào trước nút được trỏ bởi P
      Trường hợp 1: Danh sách rỗng, L=nil; (Như trên)
      Trường hợp 2: Danh sách khác rỗng.
      Để thêm vào nút đứng trước P ta cần có nút Q đứng trước P (Q^.next=P).
      + Gán Q:=L;
      + Nếu Q^.next<>p thì Q:=Q^.next; ngược lại thì chuyển qua các thao tác tạo nút mới
      và thay đổi múi nối.
Ôn thi cao học – Danh sách liên kết
Trần Hoài Nhân
                                                               -4-


                      L
                          1           4           2                3           6       7         nil
                      Q                                        P
Sau khi duyệt:
                      L
                          1           4           2                3           6       7         nil
                                              Q                P


      + Thực hiện các thao tác: New(Q1); Q1^.info:=X; Q1^.next:=p; Q^.next:=Q1;

   Trong trường hợp này có thể làm như sau: new(Q^.next); Q^.next^.info:=X;
Q^.next^.next:=P;
                              L
                                  1       4               2                3       6       nil
                                                      Q                P
                                                               7
                                                          Q1
Giải thuật:
      Procedure ThemNut(var L:tro; X:integer);
      Var Q,Q1:tro;
      Begin
          {Trường hợp 1}
            if L=nil then
              begin
                new(L); L^.info:=X; L^.next:=nil; exit;
              end;
          {Trường hợp 2}
           //Duyệt đến nút đứng trước nút P
            Q:=L;
            while Q^.next <> P do Q:=Q^.next;
          //Tạo nút mới và thay đổi các múi nối
         New(Q1); Q1^.info:=X; Q1^.next:=p; Q^.next:=Q1;
       End;

Loại bỏ một nút khỏi danh sách
  Loại bỏ nút có giá trị X ra khỏi danh sách. Ví dụ X=2

      Trường hợp 1: Nút cần loại bỏ là nút đầu danh sách: L^.info=X;
      + p:=L; L:=L^.next; Dispose(p);
      Trường hợp 2: Nút cần loại bỏ không phải là nút đầu.

      Cách 1:
      + Tìm nút đứng kế trước nút cần loại bỏ. P là nút đứng trước nút cần loại bỏ:
                                       P^.next^.info=X;
      + Thay đổi các múi nối như sau: Q:=P^.next; P^.next:=P^.next^.next; Dispose(q);


Ôn thi cao học – Danh sách liên kết
Trần Hoài Nhân
                                                     -5-


      Cách 2:
      + Tìm đến nút cần loại bỏ P, trong khi tìm sử dụng thêm một biến con trỏ Q để trỏ
      tới nút đứng liền trước P.
      + Sau khi tìm, thay đổi múi nối: Q^.next:=P^.next; dispose(P);
                        L
                            1         4          2          7       3   6   nil
                                          Q            P


Giải thuật:
      Procedure LoaiBo(var L:tro; X:integer);
      Var p,q:Tro;
      Begin
          {Trường hợp 1}
          if L^.info=X then
            begin
              P:=L;L:=L^.next;Dispose(P);
              exit;
            end;
        {Trường hợp 2}
        //Tìm nút cần loại bỏ (P trỏ vào nút cần loại bỏ)
      P:=L^.next;Q:=L;
      while (P<>nil)and(P^.info<>X) do
         begin
            Q:=P; P:=P^.next;
         end;
      Q^.next:=P^.next; dispose(P);
    End;



II. Danh sách liên kết đôi
1. Cấu trúc và khai báo

a. Cấu trúc của một nút
   - Trường Info để chứa giá trị cần lưu trữ.
   - Trường Left và Right là hai con trỏ. Left chứa địa chỉ của nút trước, dùng liên
      kết với nút trước, Right liên kết với nút sau.
                                          Left       Info       Right
      Sau đây là ví dụ về một danh sách liên kết đôi.
                            L
                  nil            1        4           2            3    6    nil


b. Khai báo
      TYPE  Tro=^Nut;
            Nut=record
                    Info:Integer;
                    Next: Tro;
                 End;
      Var L:Tro;

Ôn thi cao học – Danh sách liên kết
Trần Hoài Nhân
                                               -6-


2. Một số thuật toán

a. Duyệt danh sách
   Trong danh sách liên kết đôi, mỗi nút đều có thể liên kết được với nút trước và nút
sau nên ta có thể duyết từ nút đầu đến nút cuối và ngược lại. Cách duyệt tương tự như ở
danh sách móc nối đơn.

b. Thêm nút mới vào danh sách
   i. Thêm vào đâu danh sách
   Thực hiện các thao tác sau: New(p); p^.info:=X; P^.right:=L; P^.Left:=nil; L:=p;

      ii. Thêm vào vị trí bất kì khác vị trí đầu danh sách
      * Thêm một nút chứa giá trị X1 vào trước nút chứa giá trị X
      + Duyệt đến nút chứa giá trị X, nút đó được trỏ bởi P.
      + Nếu tìm thấy (P<>nil) thì thực hiện các thao tác sau:
          - new(Q); Q^.info:=X1; Q^.right:=P; Q^.Left:=P^.Left; {Tạo nút mới Q}
          - P^.Left:=Q; Q^.Left^.Right:=Q;                        {Thay đổi múi nối}

      * Thêm một nút chứa giá trị X1 vào sau nút chứa giá trị X. (tương tự)

b. Loại bỏ một nút khỏi danh sách
   Loại bỏ nút chứa giá trị X ra khỏi danh sách liên kết
   Trường hợp 1: Nút loại bỏ là nút đầu danh sách, L^.info=X
   + P:=L; L:=L^.Right; L^.left:=nil; dispose(p);

      Trường hợp 2: Nút loại bỏ không là nút đầu danh sách
      + Duyệt đến nút chứa giá trị X, nút đó được trỏ bởi P
      + Nếu P<>nil thì thực hiện thay đổi các múi nối như sau
       (1) P^.Left^.Rigth:=P^.Right;
       (2) P^.Right^.Left:=p^.Left;
                                           (1)
                            L
                   nil           1    4          2         3        6         nil

                                           P         (2)

                 (3) Dispose(p);
                            L
                   nil           1    4                    3        6         nil




Ôn thi cao học – Danh sách liên kết
Trần Hoài Nhân
                                                      -7-


III. Danh sách liên kết nối vòng
1. Dánh sách liên kết đơn nối vòng
                                L

                                      1       4       2           3        6


    Dánh sách liên kết đơn nối vòng là cải tiến của danh sách móc nối đơn cải tiến ở chỗ
nút cuối danh sách nối với nút đầu danh sách. Điểm lợi của cái tiến này là: Ta có thể
truy cập vào mọi nút trong danh sách bắt đầu từ một nút nào cũng được, không nhất
thiết phải từ nút đầu tiên; có thể xem mọi nút trên danh sách đều là nút đầu.
    Các thuật toán cơ bản trên đều có thể áp dụng đối với danh sách này.
    Chú ý trong quá trình duyệt: thay lệnh kiểm tra hết danh sách P<>nil bằng
P^.next<>L.
    Để khắc phục trường hợp thêm vào nút đầu danh sách và loại bỏ nút đầu danh sách
người ta thêm vào danh sách một nút đặc biệt gọi là nút đầu danh sách. Nút này không
chứa giá trị.
       L
                         1            4       2           3       6       nil


       L
                         1            4       2           3       6




2. Danh sách liên kết kép nối vòng
       L
                 1            4           2           3           6



           L
                              1           4           2           3             6



                     L
       nil                            1           4           2       3             6   nil




IV. Sử dụng danh sách liên kết làm Stack
      Sử dụng danh sách liên kết đơn là Stack.
      + Tính chất của Stack là đầu nạp dữ liệu cũng là đầu để lấy dữ liệu ra nên ta sử dụng
      cách nạp vào đầu danh sách và lấy ra ở đầu danh sách



Ôn thi cao học – Danh sách liên kết
Trần Hoài Nhân
                                            -8-


V. Sử dụng danh sách liên kết làm Queue
      Sử dụng danh sách liên kết đơn làm Queue.
      Dựa vào tính chất của Queue là có một đầu để nạp dữ liệu vào và một đầu khác để
      lấy dữ liệu ra. Nên cần có quản lý nút cuối danh sách.
      Nếu nạp vào đầu danh sách thì phải lấy ra ở cuối hoặc ngược lại.

VI. Một số bài toán cơ bản
      1. Cho một danh sách liên kết đơn, để lưu trữ dãy số tăng dần gồm n số hạng. Hãy
         thêm vào danh sách nút chứa giá trị X vào vị trí thích hợp.
      2. Tách danh sách liên kết đơn chứa dãy số đã được sắp xếp thành hai danh sách con
         Ds1 và Ds2 có số lượng các phần tử không lệch nhau quá 1. Trong đó Ds1 là
         danh sách lưu dãy sắp xếp tăng, Ds2 là danh sách lưu dãy sắp xếp giảm.
      3. Viết chương trình con ghép 2 danh sách liên kết kép Ds1 và Ds2 thành một danh
         sách. Trường hợp 1: Ds2 được nối vào sau Ds1. Trường hợp 2: Ds2 được nối vào
         đầu Ds1.




Ôn thi cao học – Danh sách liên kết
Trần Hoài Nhân

								
To top