LATEST

Tìm kiếm và sắp xếp trong DSLK đơn

Trong bài viết này, codehow sẽ hướng dẫn các bạn tìm kiếm và sắp xếp trong DSLK đơn. Đây là hai thao tác thường gặp khi sử dụng DSLK đơn cũng như các loại danh sách khác.

Việc tìm kiếm và sắp xếp với DSLk đơn rất đơn giản. Tuy nhiên các bạn cần biết DSLK đơn là gì? Cách cài đặt nó và cách thêm mới node trong DSLK đơn trước đã nhé.

Chúng ta sẽ lần lượt tìm hiểu về cách tìm kiếm một giá trị tồn tại trong danh sách và cách sắp xếp nó theo thứ tăng dần hoặc giảm dần.

Tìm kiếm trong DSLK đơn

Đối với việc tìm kiếm trong DSLK đơn cũng tương tự như trong mảng một chiều. Chúng ta sẽ duyệt từng phần tử trong danh sách, sau đó so sánh với giá trị cần tìm kiếm. Nếu bằng thì giá trị tồn tại trong danh sách, ngược lại không bằng thì không tồn tại.

bai29 01 png

Giả sử mình có giá trị index = 5 là giá trị cần tìm. Khi đó ta cần khai báo thêm node tạm pTmp, node này dùng để thay thế cho pHead duyệt danh sách.

Sử dụng vòng lặp for với điều kiện pTmp != NULL để lặp từng phần tử trong mảng. Nếu tồn tại giá trị trong mảng bằng giá trị pTmp thì thông báo tồn tại rồi thoát vòng lặp. Nếu chưa tìm thấy thì duyệt tiếp phần tử tiếp theo trong danh sách.

Dưới đây là hàm tiếm kếm giá trị d trong danh sách list mình đã viết.

/* tìm kiếm giá trị index trong danh sách */
Node * SearchNode(SingleList list,int d)
{
  Node *pTmp=list.pHead; // khai báo biến tạm pTmp thay thế cho pHead để duyệt danh sách
  //Thực hiện vòng lặp các phần tử trong danh sách với điều kiện pTmp != null
  while(pTmp!=NULL)
  {
    if(pTmp->data==d) // nếu tìm thấy index thì thoát khỏi vòng lặp
      break; // chưa tìm thấy thì tiếp tục duyệt phần tử kết tiếp
    pTmp=pTmp->pNext;
  }
  return pTmp;
}

Sắp xếp trong DSLK đơn

Đối với việc sắp xếp trong DSLK đơn, chúng ta chỉ thực hiện sắp xếp các node bằng cách thay đổi giá trị của chúng chứ không thay đổi vị trí node.

bai29 03 png

Về cơ bản thì việc sắp xếp các node trong DSLK đơn cũng giống như các thuật toán sắp xếp khác. Chúng ta chỉ việc duyệt từng node sau đó so sánh với nhau, sau đó sắp xếp chúng cho đúng thứ tự là được.

Dưới đây là hàm sắp xếp các node trong DSLK đơn, các bạn có thể tham khảo nhé. Mình sẽ giải thích ngay bên dưới.

/* sắp xếp trong danh sách liên kết đơn theo thứ tự tăng dần */
void SortList(SingleList &list)
{
  // for loop thứ nhất
 for(Node *pTmp=list.pHead;pTmp!=NULL;pTmp=pTmp->pNext)
 {
   //for loop thứ hai
  for(Node *pTmp2=pTmp->pNext;pTmp2!=NULL;pTmp2=pTmp2->pNext)
  {
    if(pTmp->data>pTmp2->data) // nếu giá trị trước > giá trị sau thì hoán đổi hai vị trí
     {
       int tmp=pTmp->data;
       pTmp->data=pTmp2->data;
       pTmp2->data=tmp;
     }
  }
 }
}

Giải thích:

  1. Sử dụng vòng lặp for để lặp từng phần tử trong danh sách.
  2. So sánh phần tử với phần tử đầu tiên. Nếu phần tử sau lớn hơn phần tử trước thì ta hoán đổi hai vị trí của chúng.
  3. Tiếp tục lặp và so sánh cho đến hết danh sách.

Ví dụ tìm kiếm và sắp xếp trong DSLK đơn

Trong phần này mình sẽ thực hiện một ví dụ tìm kiếm và sắp xếp trong DSLK đơn. Mình sẽ áp dụng các kiến thức ở các bài viết trước để các bạn ôn lại nhé. Các bạn có thể tham khảo chương trình dưới đây, mình sẽ chú thích rõ ràng trong chương trình.

#include <iostream>
using namespace std;
/* Khai báo giá trị data và con trỏ pNext trỏ tới phần tử kế tiếp */
struct Node
{
  int data;// giá trị data của node
  Node *pNext;// con trỏ pNext
};
   
/* Khai báo Node đầu pHead và Node cuối pTail*/
struct SingleList
{
  Node *pHead; //Node đầu pHead
  Node *pTail; // Node cuối pTail
};
   
/* khởi tạo giá trị cho Node đầu và Node cuối */
void Initialize(SingleList &list)
{
  list.pHead=list.pTail=NULL;// khởi tạo giá trị cho Node đầu và Node cuối là Null
}
  
/* Đếm số phần tử trong danh sách */
 int SizeOfList(SingleList list)
{
    Node *pTmp=list.pHead;
    int nSize=0;
    while(pTmp!=NULL)
    {
        pTmp=pTmp->pNext;
        nSize++;
    }
    return nSize;
}
  
/* tạo Node trong danh sách liên kết đơn */
Node *CreateNode(int d)
{
    Node *pNode=new Node; //sử dụng pNode để tạo một Node mới
    if(pNode!=NULL) // Nếu pNode != Null, tức là pNode có giá trị thì
    {
       pNode->data=d; // gán giá trị data cho d
       pNode->pNext=NULL;// và cho con trỏ pNext trỏ tới giá trị Null
    }
    else // Nếu pNode == Null, tức là pNode không có giá trị thì xuất thông tin
    {
      cout<<"Error allocated memory";
    }
    return pNode;//trả về pNode
}
  
/* chèn Node đầu danh sách */
void InsertFirst(SingleList &list,int d)
{
  Node *pNode=CreateNode(d);
  if(list.pHead==NULL)
  {
    list.pHead=list.pTail=pNode;
  }
  else
  {
    pNode->pNext=list.pHead;
    list.pHead=pNode;
  }
}
  
/* chèn node vào cuối danh sách */
void InsertLast(SingleList &list,int d)
{ 
  Node *pNode=CreateNode(d);
  if(list.pTail==NULL)
  {
    list.pHead=list.pTail=pNode;
  }
  else
  {
    list.pTail->pNext=pNode;
    list.pTail=pNode;
  }
}
  
/* chèn node vào giữa danh sách */
void InsertMid(SingleList &list, int pos, int d){
  // Nếu pos < 0 hoặc pos lớn hơn kích thước của danh sách thì reuturn
  if(pos < 0 || pos >= SizeOfList(list)){
    cout<<"Không thể chèn Node!!!";
    return;
  }
  // Nếu pos == 0 thì gọi hàm InsertFirst
  if(pos == 0){
    InsertFirst(list, d);
  }
  //Nếu pos == SizeOfList - 1 thì gọi hàm InsertLast
  else if(pos == SizeOfList(list)-1){
    InsertLast(list, d);
  }
  //Ngược lại thì thay đổi mối liên kết giữa các phần tử, cụ thể:
  else{
    Node *pNode = CreateNode(d);
    Node *pIns = list.pHead;
    Node *pPre = NULL;
    int i = 0;
    //thực hiện vòng lặp tìm pPre và pIns
    while(pIns != NULL){
      if(i == pos)
      break;
      pPre = pIns;
      pIns = pIns ->pNext;
      i++;
    }
    //sau khi tìm được thì thay đổi con trỏ pNext
    pPre ->pNext=pNode;
    pNode->pNext=pIns;
  }
}
/* tìm kiếm giá trị index trong danh sách */
Node * SearchNode(SingleList list,int d)
{
  Node *pTmp=list.pHead; // khai báo biến tạm pTmp thay thế cho pHead để duyệt danh sách
  //Thực hiện vòng lặp các phần tử trong danh sách với điều kiện pTmp != null
  while(pTmp!=NULL)
  {
    if(pTmp->data==d) // nếu tìm thấy index thì thoát khỏi vòng lặp
      break; // chưa tìm thấy thì tiếp tục duyệt phần tử kết tiếp
    pTmp=pTmp->pNext;
  }
  return pTmp;
}
 
/* sắp xếp trong danh sách liên kết đơn theo thứ tự tăng dần */
void SortList(SingleList &list)
{
  // for loop thứ nhất
 for(Node *pTmp=list.pHead;pTmp!=NULL;pTmp=pTmp->pNext)
 {
   //for loop thứ hai
  for(Node *pTmp2=pTmp->pNext;pTmp2!=NULL;pTmp2=pTmp2->pNext)
  {
    if(pTmp->data>pTmp2->data) // nếu giá trị trước > giá trị sau thì hoán đổi hai vị trí
     {
       int tmp=pTmp->data;
       pTmp->data=pTmp2->data;
       pTmp2->data=tmp;
     }
  }
 }
}
 
  
/* hàm xuất dữ liệu */
void PrintList(SingleList list)
{
  Node *pTmp=list.pHead;
  if(pTmp==NULL)
  {
    cout<<"The list is empty!";
    return;
  }
  while(pTmp!=NULL)
  {
    cout<<pTmp->data<<" ";
  pTmp=pTmp->pNext;
  }
}
  
int main() {
  SingleList list;
  Initialize(list);
  
//Thêm node đầu danh sách
  InsertFirst(list, 5);
  InsertFirst(list, 7);
  InsertFirst(list, 3);
  cout<<"Các Node trong danh sách sau khi InsertFirst là: ";
  PrintList(list);
  
//Thêm node cuối danh sách
  InsertLast(list, 4);
  InsertLast(list, 2);
  InsertLast(list, 6);
  cout<<"\nCác Node trong danh sách sau khi InsertLast là: ";
  PrintList(list);
  
//Thêm node giữa danh sách
  InsertMid(list, 4, 11);
  InsertMid(list, 2, 12);
  InsertMid(list, 3, 13);
  cout<<"\nCác Node trong danh sách sau khi InsertMid là: ";
  PrintList(list);
//Tìm kiếm giá trị index trong danh sách
  int index;
  cout<<"\nNhập vào số bạn muốn tìm: ";
  cin>>index;
  Node *pFound = SearchNode(list, index);
  if(pFound == NULL){
    cout<<"Không tìm thấy số "<<index<<" trong danh sách";
     
  }
  else{
    cout<<"Đã tìm thấy số "<<index<<" trong danh sách.";
  }
//Sắp xếp các phần tử trong danh sách
  cout<<"\nDanh sách trước khi sắp xếp: ";
  PrintList(list);
  SortList(list);
  cout<<"\nDanh sách sau khi sắp xếp: ";
  PrintList(list);
 
 
  cout<<"\n-------------------------------------\n";
  cout<<"Chương trình này được đăng tại codehow.net";
}

Kết quả:

bai29 02 png

Như vậy là chúng ta đã cùng nhau tìm hiểu về cách tìm kiếm và sắp xếp trong DSLK đơn. Ở bài viết tiếp, mình sẽ hướng dẫn các bạn viết chương trình quản lý học sinh bằng DSLK đơn.

Cùng chuyên mục:

Xóa node khỏi cây nhị phân tìm kiếm

Xóa node khỏi cây nhị phân tìm kiếm

Tìm node Max và Min trong cây nhị phân tìm kiếm

Tìm node Max và Min trong cây nhị phân tìm kiếm

Xuất node con và node lá trong cây nhị phân tìm kiếm

Xuất node con và node lá trong cây nhị phân tìm kiếm

Tìm kiếm trên cây nhị phân tìm kiếm

Tìm kiếm trên cây nhị phân tìm kiếm

Duyệt cây nhị phân tìm kiếm

Duyệt cây nhị phân tìm kiếm

Thêm node vào cây nhị phân tìm kiếm

Thêm node vào cây nhị phân tìm kiếm

Cây nhị phân (Binary tree) là gì? Cơ chế hoạt động của nó

Cây nhị phân (Binary tree) là gì? Cơ chế hoạt động của nó

Cách gộp hai danh sách liên kết đôi

Cách gộp hai danh sách liên kết đôi

Tìm kiếm phần tử trong DSLK đôi

Tìm kiếm phần tử trong DSLK đôi

Xóa node trong DSLK đôi

Xóa node trong DSLK đôi

Chèn node (Insert node) vào DSLK đôi

Chèn node (Insert node) vào DSLK đôi

Duyệt danh sách liên kết đôi

Duyệt danh sách liên kết đôi

Tạo node mới trong DSLK đôi

Tạo node mới trong DSLK đôi

DSLK đôi là gì? Cấu trúc dữ liệu của DSLK đôi

DSLK đôi là gì? Cấu trúc dữ liệu của DSLK đôi

Quản lý sinh viên bằng DSLK đơn

Quản lý sinh viên bằng DSLK đơn

Xóa node (Delete node) trong DSLK đơn

Xóa node (Delete node) trong DSLK đơn

Chèn node (Insert node) vào DSLK đơn

Chèn node (Insert node) vào DSLK đơn

Tạo node mới trong DSLK đơn

Tạo node mới trong DSLK đơn

Cấu trúc dữ liệu của DSLK đơn

Cấu trúc dữ liệu của DSLK đơn

Danh sách liên kết (Linked List) là gì? Các loại danh sách liên kết

Danh sách liên kết (Linked List) là gì? Các loại danh sách liên kết

Top