LATEST

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

Trong bài viết này, codehow sẽ hướng dẫn các bạn cách chèn node (Insert node) vào DSLK đơn. Hiểu đơn giản hơn thì việc này chính là thêm một phần tử vào trong DSLK đơn.

Trước khi bắt đầu vào bài học này, phải chẵn chắn rằng các bạn đã xem hai bài viết trước đó là: Cấu trúc dữ liệu DSLK đơncách tạo node mới trong DSLK đơn nhé. Vì đây là nền tảng để các bạn có thể thực hiện thao tác thêm node vào trong DSLK đơn.

Chúng ta sẽ tìm hiểu ba cách để thêm node (Insert node) vào trong DSLK đơn đó là: Thêm vào đầu danh sách, thêm vào cuối danh sách và thêm vào giữa danh sách.

Bây giờ các bạn cùng mình đi tìm hiểu từng cách một nhé, sau đó mình sẽ đưa ra ví dụ cụ thể cho các bạn tham khảo.

Chèn node vào đầu DSLK đơn

Để có thể chèn được node vào DSLK đơn, các bạn phải đảm bảo rằng đã cài đặt DSLK đơn và khai báo, khởi tạo node đã nhé.

Dưới đây là hàm chèn node vào đầu DSLK đơn, các bạn hãy xem đã nhé, sau đó mình giải thích ngay bên dưới.

/* chèn Node đầu danh sách */
void InsertFirst(SingleList &list,int d)
{
  Node *pNode=CreateNode(d); //tạo một node mới
//Nếu pHead == null thì pNode chính là pHead
  if(list.pHead==NULL)
  {
    list.pHead=list.pTail=pNode;
  }
// Ngược lại ta phải chèn pNode vào pHead sau đó đưa pHead ra đầu danh sách
  else
  {
    pNode->pNext=list.pHead;
    list.pHead=pNode;
  }
}

Giải thích:

Như các bạn đã biết thì một node khi được khỏi tạo sẽ có giá trị data và con trỏ pNext -> NULL. Như vậy nếu pHead == NULL nghĩa là khi thêm vào đó là phần tử đầu tiên. Nếu pHead != NULL thì ta thay đổi con trỏ trỏ từ pNext -> pHead.

//Nếu pHead == null thì pNode chính là pHead
  if(list.pHead==NULL)
  {
    list.pHead=list.pTail=pNode;
  }

bai27 01 png

Bởi vì pHead luôn luôn quản lý node đầu tiên, vậy nên sau khi trỏ đến pHead, ta cần đưa pHead về đầu danh sách: pHead -> pNode.

// Ngược lại ta phải chèn pNode vào pHead sau đó đưa pHead ra đầu danh sách
  else
  {
    pNode->pNext=list.pHead;
    list.pHead=pNode;
  }

bai27 02 png

Chèn node vào cuối DSLK đơn

Việc chèn node vào cuối DSLK đơn được thực hiện tương tự việc chèn node vào đầu DSLK đơn. Các bạn hãy xem hàm chèn node vào cuối DSLK đơn, sau đó mình sẽ giải thích rõ ngay bên dưới.

/* chèn node vào cuối danh sách */
void InsertLast(SingleList &list,int d)
{ 
  Node *pNode=CreateNode(d); // tạo node mới
// Nếu pTail == null thì pNode chính là pTail
  if(list.pTail==NULL)
  {
    list.pHead=list.pTail=pNode;
  }
// Ngược lại nếu pTail != null thì chèn pNode vào pTail và đưa pTail ra cuối danh sách
  else
  {
    list.pTail->pNext=pNode;
    list.pTail=pNode;
  }
}

Giải thích:

Đầu tiên ta kiểm tra xem nếu pTail == NULL, nghĩa là node thêm vào chính là node cuối cùng, khi đó chúng ta không cần thay đổi con trỏ pNext.

// Nếu pTail == null thì pNode chính là pTail
  if(list.pTail==NULL)
  {
    list.pHead=list.pTail=pNode;
  }

bai27 03 png

Nếu pTail != NULL, nghĩa là node thêm vào không phải node cuối. Khi đó ta cần thay đổi con trỏ pNext để node thêm vào chính là node cuối cùng. Sau khi thay đổi con trỏ pNext, ta cần đưa pTail về cuối danh sách, bởi vì nó luôn luôn quản lý node cuối trong danh sách.

// Ngược lại nếu pTail != null thì chèn pNode vào pTail và đưa pTail ra cuối danh sách
  else
  {
    list.pTail->pNext=pNode;
    list.pTail=pNode;
  }

bai27 04 png

Chèn node vào giữa DSLK đơn

Chèn node vào giữa DSLK đơn nghĩa là chèn vào một vị trí bất kì nằm giữa DSLK đơn. Khi đó ta cần thêm các con trỏ,biến và hàm sau đây:

  • pPre là node đứng trước node cần chèn.
  • pIsn là node đứng sau node cần chèn.
  • Tham số pos là vị trí cần chèn.
  • Tham số d là giá trị cần chèn.
  • Hàm SizeOfList() để lấy kích thước của danh sách.

Các bạn hãy xem hàm chèn node vào giữa DSLK đơn dưới đây. Đầu tiên là hàm SizeOfLIst() để lấy kích thước, sau đó là hàm InsertMid() để chèn node vào giữa DSLK đơn.

SizeOfList()
/* Đế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;
}
InsertMid()
/* 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;
  }
}

Giải thích:

Đầu tiên chúng ta cần kiểm tra xem nếu vị trí chèn pos lớn hơn kích thước của danh sách thì thông báo không thể chèn.

InsertMid()
// 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;
  }

Kiểm tra xem nếu vị trí cần chèn là vị trí đầu thì gọi hàm InsertFirst(), nếu là vị trí cuối thì gọi hàm InsertLast().

InsertMid()
// 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);
  }

Còn lại các trường hợp khác thì chúng ta chỉ cần thay đổi mối liên kết của node là xong.

InsertMid()
pPre ->pNext=pNode;
pNode->pNext=pIns;

bai27 05 png

Ví dụ chèn node vào DSLK đơn trong C / C++

Trong phần này mình sẽ thực hiện một chương trình để áp dụng các kiến thức đã học nhé. Chương trình sẽ thực hiện cài đặt cấu trúc dữ liệu của DSLK đơn, tạo node và chèn node. Mình sẽ thực hiện cả ba cách chèn node để các bạn có thể tham khảo.

/* 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;
  }
}
 
/* 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 5, 7, 3 trong danh sách sau khi InsertFirst là: \n";
  PrintList(list);
 
//Thêm node cuối danh sách
  InsertLast(list, 4);
  InsertLast(list, 2);
  InsertLast(list, 6);
  cout<<"\nCác Node 4, 2, 6 trong danh sách sau khi InsertLast là: \n";
  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 11, 12, 13 sau khi Insert vào vị trí 4, 2, 3 là: \n";
  PrintList(list);
 
  cout<<"\n-------------------------------------\n";
  cout<<"Chương trình này được đăng tại codehow.net";
}

Kết quả:

bai27 06 png

Như vậy là chúng ta đã cùng nhau tìm hiểu về các cách chèn node (Insert node) vào DSLK đơn. Ở bài viết tiếp theo mình sẽ hướng dẫn các bạn cách xóa node trong DSLK đơn. Các bạn chú ý theo dõi nhé, cảm ơn các bạn rất nhiều.

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

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

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

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

Xóa node (Delete node) trong 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