MFC – 链表

MFC – 链表


链表是线性数据结构,其中每个元件是一个单独的对象。列表的每个元素(我们称之为节点)都包含两个项目——数据和对下一个节点的引用。最后一个节点引用了 null。

链表是由一组节点组成的数据结构,这些节点共同表示一个序列。它是一种用结构存储数据的方法,以便程序员可以在必要时自动创建一个新位置来存储数据。它的一些显着特点是 –

  • 链接列表是包含项目的链接序列。

  • 每个链接都包含到另一个链接的连接。

  • 列表中的每一项都称为一个节点。

  • 如果列表至少包含一个节点,则新节点将定位为列表中的最后一个元素。

  • 如果列表只有一个节点,则该节点表示第一项和最后一项。

有两种类型的链接列表 –

单链表

单向链表是一种数据结构。在单向链表中,链表中的每个节点都存储该节点的内容以及指向链表中下一个节点的指针或引用。

单链表

双向链表

双向链表是一种链接数据结构,由一组称为节点的顺序链接记录组成。每个节点包含两个字段,它们是对节点序列中前一个节点和下一个节点的引用。

双链表

CList 类

MFC 提供了一个CList,它是一个模板链表实现并且工作得很好。CList 列表的行为类似于双向链表。POSITION 类型的变量是列表的键。您可以将 POSITION 变量用作迭代器来按顺序遍历列表,也可以将其用作书签来保存某个位置。

以下是对 CList 对象的不同操作 –

创建 CList 对象

要创建 CList 值或对象的集合,您必须首先决定集合的值的类型。您可以使用现有的基本数据类型之一,例如 int、CString、double 等,如下面的代码所示。

CList<double, double>m_list;

添加项目

要添加项目,您可以使用 CList::AddTail() 函数。它在列表的末尾添加一个项目。要在列表的开头添加元素,您可以使用 CList::AddHead() 函数。在 OnInitDialog() CList 中,创建对象并添加四个值,如下面的代码所示。

CList<double, double>m_list;

//Add items to the list
m_list.AddTail(100.75);
m_list.AddTail(85.26);
m_list.AddTail(95.78);
m_list.AddTail(90.1);

检索项目

POSITION 类型的变量是列表的键。您可以使用 POSITION 变量作为迭代器来按顺序遍历列表。

Step 1 – 要从列表中检索元素,我们可以使用以下代码来检索所有值。

//iterate the list
POSITION pos = m_list.GetHeadPosition();
while (pos) { 
   double nData = m_list.GetNext(pos);
   CString strVal;
   strVal.Format(L"%.2f\n", nData);
   m_strText.Append(strVal);
}

第 2 步– 这是完整的 CMFCCListDemoDlg::OnInitDialog() 函数。

BOOL CMFCCListDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);             // Set big icon
   SetIcon(m_hIcon, FALSE);             // Set small icon

   // TODO: Add extra initialization here
   CList<double, double>m_list;

   //Add items to the list
   m_list.AddTail(100.75);
   m_list.AddTail(85.26);
   m_list.AddTail(95.78);
   m_list.AddTail(90.1);

   //iterate the list
   POSITION pos = m_list.GetHeadPosition();
   while (pos) {
      double nData = m_list.GetNext(pos);
      CString strVal;
      strVal.Format(L"%.f\n", nData);
      m_strText.Append(strVal);
   }

   UpdateData(FALSE);
 
   return TRUE; // return TRUE unless you set the focus to a control
}

Step 3 – 编译并执行上述代码后,您将看到以下输出。

取回

在中间添加项目

要在列表中间添加项目,您可以使用 CList::.InsertAfter() 和 CList::.InsertBefore() 函数。它需要两个参数 – 首先是位置(可以添加的位置),其次是值。

步骤 1 – 让我们插入一个新项目,如下面的代码所示。

BOOL CMFCCListDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();
   
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);             // Set big icon
   SetIcon(m_hIcon, FALSE);          // Set small icon

   // TODO: Add extra initialization here
   CList<double, double>m_list;

   //Add items to the list
   m_list.AddTail(100.75);
   m_list.AddTail(85.26);
   m_list.AddTail(95.78);
   m_list.AddTail(90.1);

   POSITION position = m_list.Find(85.26);
   m_list.InsertBefore(position, 200.0);
   m_list.InsertAfter(position, 300.0);

   //iterate the list
   POSITION pos = m_list.GetHeadPosition();
   while (pos) {
      double nData = m_list.GetNext(pos);
      CString strVal;
      strVal.Format(L"%.2f\n", nData);
      m_strText.Append(strVal);
   }

   UpdateData(FALSE);

   return TRUE; // return TRUE unless you set the focus to a control
}

第 2 步– 您现在可以看到我们首先检索值 85.26 的位置,然后在该值之前和之后插入一个元素。

Step 3 – 编译并执行上述代码后,您将看到以下输出。

添加项目

更新项目值

要更新数组中间的项目,可以使用 CArray::.SetAt() 函数。它需要两个参数——第一个是位置,第二个是值。

让我们将列表中的 300.00 更新为 400,如下面的代码所示。

BOOL CMFCCListDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);              // Set big icon
   SetIcon(m_hIcon, FALSE);            // Set small icon

   // TODO: Add extra initialization here
   CList<double, double>m_list;

   //Add items to the list
   m_list.AddTail(100.75);
   m_list.AddTail(85.26);
   m_list.AddTail(95.78);
   m_list.AddTail(90.1);

   POSITION position = m_list.Find(85.26);
   m_list.InsertBefore(position, 200.0);
   m_list.InsertAfter(position, 300.0);

   position = m_list.Find(300.00);
   m_list.SetAt(position, 400.00);

   //iterate the list
   POSITION pos = m_list.GetHeadPosition();
   while (pos) {
      double nData = m_list.GetNext(pos);
      CString strVal;
      strVal.Format(L"%.2f\n", nData);
      m_strText.Append(strVal);
   }

   UpdateData(FALSE);

   return TRUE; // return TRUE unless you set the focus to a control
}

当上面的代码编译执行后,你会看到下面的输出。您现在可以看到 300.00 的值更新为 400.00。

更新项目

删除项目

要删除任何特定项目,您可以使用 CList::RemoveAt() 函数。要从列表中删除所有元素,可以使用 CList::RemoveAll() 函数。

让我们删除元素,它的值为 95.78。

BOOL CMFCCListDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);              // Set big icon
   SetIcon(m_hIcon, FALSE);             // Set small icon

   // TODO: Add extra initialization here
   CList<double, double>m_list;

   //Add items to the list
   m_list.AddTail(100.75);
   m_list.AddTail(85.26);
   m_list.AddTail(95.78);
   m_list.AddTail(90.1);

   POSITION position = m_list.Find(85.26);
   m_list.InsertBefore(position, 200.0);
   m_list.InsertAfter(position, 300.0);
   
   position = m_list.Find(300.00);
   m_list.SetAt(position, 400.00);

   position = m_list.Find(95.78);
   m_list.RemoveAt(position);

   //iterate the list
   POSITION pos = m_list.GetHeadPosition();
   while (pos) {
      double nData = m_list.GetNext(pos);
      CString strVal;
      strVal.Format(L"%.2f\n", nData);
      m_strText.Append(strVal);
   }
   UpdateData(FALSE);
   
   return TRUE; // return TRUE unless you set the focus to a control
}

当上面的代码编译执行后,你会看到下面的输出。您现在可以看到 95.78 的值不再是列表的一部分。

删除项目

觉得文章有用?

点个广告表达一下你的爱意吧 !😁