文章类型: VC&C++
关键词: VC,列表,CListCtrl,链表,List,字典,CMap,数组,数列,可选,排序
内容摘要: VC中使用列表CListCtrl、链表List、字典CMap、数组等完成一组数列的可选排序问题

VC中使用列表CListCtrl、链表List、字典CMap、数组等实现一组数列的可选排序

2017/11/7 13:49:34    来源:apple    阅读:

如下图的实现效果:

blob.png

定义的主要变量如下:

CString strSelectMoveCaseColumn = "";//当前选择的可移动操作列的名称
SList selectCaseColumnList;//也可以使用系统提供的CList链表实现
CButton* pCheckBoxButton;//动态生成的复选按钮指针
CButton* pRadioButton;//动态生成的单选按钮指针
CString allCaseColumnArr[15];//所有病例列名称数组
CMap<CString, LPCTSTR, int, int> caseColumnWidthDic;//所有的病例列宽度的字典集合
CListCtrlCl m_list_caseSetSelect;//已经扩展的列表控件

其中SList为自定义的链表类,实现选择列的保存、移动、查找等操作。该类下面给出具体实现:

// SList.h: interface for the SList class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SLIST_H__E5586ECB_C639_4861_8A14_7AFFA8E85DA4__INCLUDED_)
#define AFX_SLIST_H__E5586ECB_C639_4861_8A14_7AFFA8E85DA4__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef ALTSTR_H
#define ALTSTR_H
#include <atlstr.h>
#endif // !ALTSTR_H

class SList  
{
	struct Node
	{
		CString data;
		Node *next;
	}; 

	Node *head,*tail,*current,*prior;
public:
	SList();
	virtual ~SList();

	bool Move(long i);
	void ClearList();
	bool SetData(CString e);
	bool GetData(CString &e);
	bool GetData(long i, CString &e);
	long ListLength();
	bool IsEmpty();
	bool InsList(long i, CString e);
	bool DelList(long i);
	bool Locate(CString e);
	long Search(CString e);//查找字符串e的位置,如果找到了,返回其在链表中的位置值(元素位置的开始值为1),如果没有找到,返回值为-1
	bool Move(long pos, int times, bool bMoveHeadDirection);//pos为移动元素的位置;times为移动的次数;bMoveHeadDirection为移动的方向,值为true时表示向链表的头部移动,为false时表示向链表的尾部移动;返回值为true时表示移动成功,值为false时表示移动失败。
	bool MoveToHead(long pos);//pos为移动元素的位置,将此元素移动到链表的头部。
	bool MoveToTail(long pos);//pos为移动元素的位置,将此元素移动到链表的尾部。
	int Print(long i);
	void AppList(CString e);
};

#endif // !defined(AFX_SLIST_H__E5586ECB_C639_4861_8A14_7AFFA8E85DA4__INCLUDED_)
// SList.cpp: implementation of the SList class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SList.h"
#include <stdio.h>
#include<iostream>
using namespace std;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

SList::SList()
{
	head = tail = current = prior = NULL;
}

SList::~SList()
{
	ClearList();
}

void SList::AppList(CString e)//从链表的尾部插入值为e的结点
{
	Node *pn;
	pn = new Node;
	pn->data = e;
	pn->next = NULL;
	if (tail == NULL)   //链表为空时  
	{
		head = tail = pn;
	}
	else
	{
		tail->next = pn; //pn为链表尾
		tail = pn;
	}
}

int SList::Print(long i) //输出第i个结点的值
{
	Node *p = NULL, *q = NULL;
	int j = 1;
	if (IsEmpty() || i <= 0)return false;//链表为空或i不合法
	p = head;
	while (p != NULL&&j < i)//头结点的下一个结点不空
	{
		q = p;
		p = p->next;
		j++;        //指针依次向后移动直至到达i结点
	}
	if (p != NULL)   //i结点的值不空时才输出
	{
		current = p;   //更新current结点
		prior = q;     //更新prior结点
		cout << p->data << " ";
	}
	else return 1;  //不成功返回1
}


bool SList::Locate(CString e)  //如果链表中有包含数据项e的结点,
{                          //则将当前指针指向该结点,成功返回真
	Node *p = NULL, *q = NULL;    //定义两个结点
	if (IsEmpty())
	{
		return false;//链表为空或i值不合法
	}

	p = head;
	while (p != NULL&&p->data != e)//while循环,使p移动到数据项为e的结点
	{
		q = p;
		p = p->next;
	}
	if (p != NULL) //p不为空,即找到了数据项为e的结点
	{
		current = p;
		prior = q;
		return true;
	}
	else
	{
		return false;
	}
}

//查找字符串e的位置,如果找到了,返回其在链表中的位置值(元素位置的开始值为1),如果没有找到,返回值为-1
long SList::Search(CString e)  //如果链表中有包含数据项e的结点,
{
	long retPos = -1;
	//则将当前指针指向该结点,返回其在链表中的位置值,如果没有找到,返回值为-1
	if (IsEmpty())
	{
		retPos = -1;
		return retPos;//链表为空或i值不合法
	}

	retPos = 1;
	Node *p = NULL, *q = NULL;    //定义两个结点
	p = head;
	while (p != NULL&&p->data != e)//while循环,使p移动到数据项为e的结点
	{
		q = p;
		p = p->next;
		retPos++;
	}

	if (p != NULL) //p不为空,即找到了数据项为e的结点
	{
		current = p;
		prior = q;
	}
	else
	{
		retPos = -1;
	}

	p = q = NULL;
	return retPos;
}

//pos为移动元素的位置;times为移动的次数;bMoveHeadDirection为移动的方向,值为true时表示向链表的头部移动,为false时表示向链表的尾部移动;返回值为true时表示移动成功,值为false时表示移动失败。
bool SList::Move(long pos, int times, bool bMoveHeadDirection)
{
	bool bMoveResult = false;
	//则将当前指针指向该结点,返回其在链表中的位置值,如果没有找到,返回值为-1
	if (IsEmpty())
	{
		return bMoveResult;//链表为空
	}

	if (Move(pos) == false) //移动到第pos个结点,即移动到pos位置
	{
		return false;//移动到pos位置失败
	}

	Node *p = NULL, *q = NULL;    //定义两个结点
	if (bMoveHeadDirection)
	{
		while (times > 0)//while循环,使p移动到数据项为e的结点
		{
			p = current;
			if (p != NULL && prior != NULL)
			{
				if (pos > 2)
				{
					long listLength = ListLength();
					q = prior;
					if (Move(pos - 1) == false) //移动到第pos-1个结点,即移动到pos-1位置
					{
						return false;//移动到pos位置失败
					}
					q->next = p->next;
					p->next = q;
					prior->next = p;
					current = p;

					if (pos == listLength)
					{
						//表示pos处于链表的尾部
						q->next = NULL;
						tail = q;
					}
				}
				else
				{
					prior->next = current->next;
					current->next = prior;
					head = current;
					prior = NULL;
				}
			}

			times--;
		}
	}
	else
	{
		while (times > 0)//while循环,使p移动到数据项为e的结点
		{
			p = current;
			long listLength = ListLength();
			long posToTail = listLength - pos;
			if (posToTail > 0)
			{
				if (prior == NULL)
				{
					q = current->next;
					p->next = q->next;
					q->next = p;
					head = q;
				}
				else if (prior != NULL  && p->next != NULL)
				{
					if (posToTail > 1)
					{
						q = current->next;
						p->next = q->next;
						q->next = p;
						prior->next = q;
					}
					else
					{
						if (posToTail == 1)
						{
							q = current->next;
							prior->next = q;
							q->next = p;
							p->next = NULL;
							tail = p;
						}
					}
				}

				if (Move(pos + 1) == false) //移动到第pos-1个结点,即移动到pos-1位置
				{
					return false;//移动到pos位置失败
				}
			}
			else
			{
				return false;//移动到pos位置失败
			}
			
			times--;
		}
	}

	p = q = NULL;
	return true;
}

//pos为移动元素的位置,将此元素移动到链表的头部。
bool SList::MoveToHead(long pos)
{
	bool bMoveResult = false;
	//则将当前指针指向该结点,返回其在链表中的位置值,如果没有找到,返回值为-1
	if (IsEmpty())
	{
		return bMoveResult;//链表为空
	}

	if (Move(pos) == false) //移动到第pos个结点,即移动到pos位置
	{
		return false;//移动到pos位置失败
	}

	if (current != NULL && prior != NULL)
	{
		if (current->next != NULL)
		{
			if (pos > 1)
			{
				prior->next = current->next;
				current->next = head;
				head = current;
				prior = NULL;
			}
		}
		else
		{
			//表示当前移动的元素位于链表的尾部
			prior->next = NULL;
			current->next = head;
			head = current;
			tail = prior;
			prior = NULL;
		}
	}

	return true;
}

//pos为移动元素的位置,将此元素移动到链表的尾部。
bool SList::MoveToTail(long pos)
{
	bool bMoveResult = false;
	//则将当前指针指向该结点,返回其在链表中的位置值,如果没有找到,返回值为-1
	if (IsEmpty())
	{
		return bMoveResult;//链表为空
	}

	if (Move(pos) == false) //移动到第pos个结点,即移动到pos位置
	{
		return false;//移动到pos位置失败
	}

	if (current != NULL)
	{
		if (prior != NULL)
		{
			prior->next = current->next;
			current->next = NULL;
			tail->next = current;
			tail = current;
		}
		else
		{
			head = current->next;
			current->next = NULL;
			tail->next = current;
			tail = current;
		}
	}

	return true;
}

bool SList::DelList(long i)//删除第i个结点,成功返回真
{
	if (Move(i) == false) //移动到第i个结点
	{
		return false;
	}

	if (prior != NULL)   //不是头结点
	{
		prior->next = current->next;
		if (current == tail)//在尾结点处
		{
			prior->next = NULL;
			tail = prior;
			delete current;
		}
		else
		{
			delete current;
		}
	}
	else
	{
		head = current->next;
		delete current;
	}

	prior = current = NULL;  //是头结点时
	return true;
}

bool SList::InsList(long i, CString e)//在第i个结点处插入值为e的新结点,成功返回真
{
	Node *p;
	if (Move(i) == false)  //移动到第i个结点
	{
		return false;
	}

	p = new Node;  //建立新结点
	p->data = e;
	if (prior != NULL) //要插入的结点不是头结点
	{
		prior->next = p;
		p->next = current;
	}
	else   //要插入的结点是头结点
	{
		head = p;
		p->next = current;
	}

	p = NULL;
	return true;
}

bool SList::GetData(CString &e)//获得当前指针指向的值,成功返回真
{
	if (current == NULL)
	{
		return false;
	}
	else
	{
		e = current->data;
		return true;
	}
}

bool SList::SetData(CString e)//修改当前指针指向结点的值为e,成功返回真
{
	if (current == NULL)
	{
		return false;
	}
	else
	{
		current->data = e;
		return true;
	}
}

bool SList::IsEmpty()//链表是否为空
{
	if (head == NULL)
	{
		return true;
	}

	return false;
}

long SList::ListLength()//计算表长
{
	long count = 0;
	Node *p;
	p = head;
	if (p != NULL)
	{
		count++;
		while (p != tail)
		{
			p = p->next;
			count++;
		}
	}

	p = NULL;
	return count;
}

bool SList::GetData(long i, CString &e)//获得链表中第i个元素的值,成功返回真
{
	if (Move(i) == false)
	{
		return false;
	}
	else
	{
		e = current->data;
		return true;
	}
}

void SList::ClearList()//置空表
{
	Node *p, *q;
	p = head;
	while (p != tail)
	{
		q = p;
		p = p->next;
		delete q;
	}

	p = q = NULL;
	head = tail = current = prior = NULL;
}

bool SList::Move(long i)//移动当前指针到第i个结点,成功返回真
{
	bool bMoveResult = false;
	Node *p = NULL, *q = NULL;
	int j = 1;
	if (IsEmpty() || i <= 0)
	{
		return bMoveResult;
	}
	else
	{
		if (i == 1)
		{
			current = head;
			bMoveResult = true;
		}
		else
		{
			p = head->next;
			j++;//添加j++,否则当前定位的指针向后面多移动了一个位置
			while (p != NULL&&j < i)
			{
				q = p;
				p = p->next;
				j++;
			}

			if (p != NULL)
			{
				current = p;
				if (q == NULL)
				{
					prior = head;
				}
				else
				{
					prior = q;
				}
				bMoveResult = true;
			}
			else
			{
				bMoveResult = false;
			}
		}
	}

	p = q = NULL;
	return bMoveResult;
}


↑ 上一篇文章:VC CComboBox用法 关键词:VC,CComboBox,用法 发布日期:2017/11/7 11:41:38
↓ 下一篇文章:VC中常用的数据类型之间的转换string/LPCTSTR/LPSTR/VARIANT等 关键词:VC,数据类型,转换,string,LPCTSTR,LP.. 发布日期:2017/11/8 10:51:39
相关文章:
VC中给列表控件CListCtrl添加复选框 关键词:VC中给列表控件CListCtrl添加复选框 发布日期:2017-10-14 17:08
VC中CListCtrl使用技巧 关键词:VC中CListCtrl使用技巧,,listview,report,processing,nul.. 发布日期:2016-11-15 08:40
VC中的CListCtrl 失去焦点仍然显示选中高亮 关键词:VC,C++,CListCtrl,失去,焦点,仍然,显示,选中,高亮 发布日期:2018-10-24 15:59
相关目录:.NETVC&C++软件开发
我要评论
正在加载评论信息......