MFC - 链接列表

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

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

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

  • 每个链接都包含与另一个链接的连接.

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

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

  • 如果列表只有一个节点,那么该节点代表第一个和最后一个项目.

有两种类型的链接列表 :

单链接列表

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

单个链接列表

双重链接列表

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

双链表

CList类

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

Sr.No.姓名&说明
1

AddHead

将一个元素(或另一个列表中的所有元素)添加到列表的头部(换个新头).

2

AddTail

将一个元素(或另一个列表中的所有元素)添加到列表尾部(创建一个新尾部).

3

Find

获取由指针值指定的元素的位置.

4

FindIndex

获取由零基索引指定的元素的位置.

5

GetAt

获取给定位置的元素.

6

GetCount

返回元素数量这个清单.

7

GetHead

返回列表的head元素(不能为空).

8

GetHeadPosition

返回列表头元素的位置.

9

GetNext

获取迭代的下一个元素.

10

GetPrev

获取上一个元素迭代.

11

GetSize

返回此列表中元素的数量.

12

GetTail

退货列表的尾部元素(不能为空).

13

GetTailPosition

返回尾巴的位置列表的元素.

14

InsertAfter

在给定位置后插入一个新元素.

15

InsertBefore

在给定位置前插入一个新元素.

16

IsEmpty

测试空列表条件(无元素).

17

RemoveAll

从此列表中删除所有元素.

18

RemoveAt

从列表中删除元素,由位置指定.

19

RemoveHead

从列表头部删除元素.

20

RemoveTail

从列表尾部删除元素.

21

SetAt

设置给定位置的元素.

以下是对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变量作为迭代器来顺序遍历列表.

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

步骤3 : 编译并执行上面的代码时,您将看到以下输出.

Retrieve

在中间添加项目

要在列表中间添加项目,可以使用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的位置,然后在该值之前插入了一个元素,并在该值之后插入了一个元素.

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

删除项目