📜  MFC-链表

📅  最后修改于: 2020-11-20 06:35:00             🧑  作者: Mango


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

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

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

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

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

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

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

链接列表有两种类型-

单链表

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

单链表

双链表

双链表是一种由一组顺序链接的记录(称为节点)组成的链接数据结构。每个节点包含两个字段,这些字段引用节点序列中的上一个节点和下一个节点。

双链表

CList类

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

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

创建CList对象

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

CListm_list;

新增项目

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

CListm_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变量作为迭代器来顺序遍历列表。

步骤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
   CListm_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
}

步骤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
   CListm_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的位置,然后在该值之前插入了一个元素,然后在该值之后插入了一个元素。

步骤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
   CListm_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
   CListm_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的值不再是列表的一部分。

移除物品