⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sortwnd.cpp

📁 包含八种排序算法的界面演示多线程程序,以线段形式表示数据大小,排序一清二楚
💻 CPP
字号:
// SortWnd.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "SortWnd.h"
#define perbut 19/20
#define persort 7/8
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
int *a;
int Num_Run=100;
/////////////////////////////////////////////////////////////////////////////
// SortWnd
VOID ThreadProc(CSort* sort)
{
	sort->Sort();
	Num_Run--;
};
IMPLEMENT_DYNCREATE(SortWnd, CFrameWnd)

SortWnd::SortWnd()
{
	IsStarted=FALSE;
	IsPaused=FALSE;
	SleepTime=1;
	HZ=50;
	Num_Data=600;
	DataWidth=250;
	BaseData=10;
	Per_SC=60;
	CWnd* p=GetDesktopWindow();
	p->GetClientRect(&DeskRect);
	DeskRect.bottom-=30;
	Create(NULL,"数据结构--多线程排序算法的比较。编写:04级6班 李红亮。工具:Visual C++ 6.0  界面库:MFC",WS_OVERLAPPEDWINDOW,DeskRect);
	StartButton=new CButton();
	PauseButton=new CButton();
	ASCButton=new CButton();
	DSCButton=new CButton();
	RandButton=new CButton();
	SettingButton=new CButton();
	BiggerButton=new CButton();
	SmallerButton=new CButton();
	BiggerButton->Create("增大",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(DeskRect.right/2-100,DeskRect.bottom-100,DeskRect.right/2-20,DeskRect.bottom-70),this,IDB_BIGGER);
	SmallerButton->Create("缩小",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(DeskRect.right/2-100,DeskRect.bottom-100,DeskRect.right/2-20,DeskRect.bottom-70),this,IDB_SMALLER);
	StartButton->Create("开始",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(DeskRect.right/2-100,DeskRect.bottom-100,DeskRect.right/2-20,DeskRect.bottom-70),this,IDB_START);
	PauseButton->Create("暂停",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(DeskRect.right/2+20,DeskRect.bottom-100,DeskRect.right/2+100,DeskRect.bottom-70),this,IDB_PAUSE);
	ASCButton->Create("升序化",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(DeskRect.right/2+20,DeskRect.bottom-100,DeskRect.right/2+100,DeskRect.bottom-70),this,IDB_ASC);
	DSCButton->Create("降序化",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(DeskRect.right/2+20,DeskRect.bottom-100,DeskRect.right/2+100,DeskRect.bottom-70),this,IDB_DSC);
	RandButton->Create("随机化",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(DeskRect.right/2+20,DeskRect.bottom-100,DeskRect.right/2+100,DeskRect.bottom-70),this,IDB_RAND);
	SettingButton->Create("设置",WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON,CRect(DeskRect.right/2+20,DeskRect.bottom-100,DeskRect.right/2+100,DeskRect.bottom-70),this,IDB_SETTING);
	dlg=new CSettingDlg(this);
	PauseButton->EnableWindow(FALSE);
	SetButtonPos();
	Set();
	OnRandButton();
	this->SetIcon(AfxGetApp()->LoadIcon(IDI_ICON1),TRUE);
}

SortWnd::~SortWnd()
{
	delete StartButton;
	delete PauseButton;
	delete ASCButton;
	delete DSCButton;
	delete RandButton;
}


BEGIN_MESSAGE_MAP(SortWnd, CFrameWnd)
	ON_COMMAND(IDB_START,OnStartButton)
	ON_COMMAND(IDB_PAUSE,OnPauseButton)
	ON_COMMAND(IDB_ASC,OnASCButton)
	ON_COMMAND(IDB_DSC,OnDSCButton)
	ON_COMMAND(IDB_RAND,OnRandButton)
	ON_COMMAND(IDB_SETTING,OnSettingButton)
	ON_COMMAND(IDB_BIGGER,OnBiggerButton)
	ON_COMMAND(IDB_SMALLER,OnSmallerButton)
	//{{AFX_MSG_MAP(SortWnd)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_WM_SIZE()
	ON_WM_CLOSE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void SortWnd::OnStartButton()
{
	if (IsStarted)
	{
		for (int i=0;i<MAX;i++)
			if (ThreadHandle[i])
			{
				if (sort[i]->State2!=2) sort[i]->SetExitEvent();
				ThreadHandle[i]=0;
			}
		for (i=0;i<MAX;i++) if (sort[i])  while (sort[i]->State2==-1) Sleep(10);
		KillTimer(1);
		StartButton->SetWindowText("开始");
		PauseButton->EnableWindow(FALSE);
		EnableButtons(TRUE);
		IsStarted=FALSE;
//		Set();
		for (i=0;i<MAX;i++) if (sort[i]) sort[i]->Draw();
		dlg->GetDlgItem(IDOK)->EnableWindow();
		dlg->GetDlgItem(IDAPPLY)->EnableWindow();
		return;
	}
	IsStarted=TRUE;
	dlg->GetDlgItem(IDOK)->EnableWindow(FALSE);
	dlg->GetDlgItem(IDAPPLY)->EnableWindow(FALSE);
	Num_Run=Num_Sort;
	Set();
	for (int i=0;i<MAX;i++)
		if (ThreadHandle[i])
		{
			sort[i]->SetStartEvent();
			ResumeThread(ThreadHandle[i]);	
		}
	UsedTime=0;
	LastTime=GetTickCount();
	SetTimer(1,HZ,NULL);
	StartButton->SetWindowText("停止");
	PauseButton->EnableWindow();
	EnableButtons(FALSE);
//	MessageBox("Start");
}
void SortWnd::OnPauseButton()
{
	if (!IsPaused)
	{
		KillTimer(1);
		StartButton->EnableWindow(FALSE);
		for (int i=0;i<MAX;i++) if (ThreadHandle[i]) SuspendThread(ThreadHandle[i]);
		IsPaused=TRUE;
		PauseButton->SetWindowText("继续");
		return;
	}
	LastTime=GetTickCount();
	SetTimer(1,HZ,NULL);
	PauseButton->SetWindowText("暂停");
	for (int i=0;i<MAX;i++) if (ThreadHandle[i]) ResumeThread(ThreadHandle[i]);
	IsPaused=FALSE;
	StartButton->EnableWindow(TRUE);	
//	MessageBox("Pause");
}
/////////////////////////////////////////////////////////////////////////////
// SortWnd message handlers

int SortWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	memset(sort,0,4*MAX);
	memset(ThreadHandle,0,4*MAX);
	Num_Sort=7;
	sort[0]=new CBubbleSort();
	sort[1]=new CSelectionSort();
	sort[2]=new CInsertSort();
	sort[3]=new CQuickSort();
	sort[4]=new CMergeSort();
	sort[5]=new CHeapSort();
//	sort[6]=new CSelectionSort();
	sort[7]=new CShellSort();
	//ThreadHandle[i]=CreateThread(0,0,(LPTHREAD_START_ROUTINE)ThreadProc,(LPVOID)sort[i],CREATE_SUSPENDED ,&ThreadId[i]);
	return 0;
}
///        CWnd * parent,int * data,int nn,RECT * r,int b,int l

void SortWnd::OnPaint() 
{
	CFrameWnd::OnPaint();
	Draw();
	// Do not call CFrameWnd::OnPaint() for painting messages
}

void SortWnd::Set()
{
	int count=0;
	for (int i=0;i<MAX;i++)
		if (sort[i])
		{
			if (!ThreadHandle[i]) ThreadHandle[i]=CreateThread(0,0,(LPTHREAD_START_ROUTINE)ThreadProc,(LPVOID)sort[i],CREATE_SUSPENDED ,&ThreadId[i]);
			ASSERT(ThreadHandle[i]);
			RECT r;
			SetRect(&r,count);
			sort[i]->Set(this,Num_Data,&r,BaseData,DataWidth,SleepTime);
			count++;
		}
}

void SortWnd::OnDestroy() 
{
	CFrameWnd::OnDestroy();
}

void SortWnd::OnTimer(UINT nIDEvent) 
{
	DWORD t=GetTickCount();
	UsedTime+=t-LastTime;
	for (int i=0;i<MAX;i++) 
		if (sort[i]) 
		{
			if (sort[i]->IsRunning()) sort[i]->SetTime(UsedTime);
			sort[i]->Draw();
		}
	LastTime=t;
	if (Num_Run==0) OnStartButton();
	CFrameWnd::OnTimer(nIDEvent);
}

void SortWnd::SetRect(RECT *r,int count)
{
	int max;
	if (Num_Sort>4) max=4;else max=Num_Sort;
	int wid=(DeskRect.right-DeskRect.left)/max;
	int h=(DeskRect.bottom-DeskRect.top)*persort;
	int hei=h/((Num_Sort-1)/4+1);
	r->left=(count%4)*wid;
	r->right=r->left+wid;
	r->top=(count/4)*hei;
	r->bottom=r->top+hei-TextHeight;
}

void SortWnd::SetButtonPos()
{
	SIZE size;
	SIZE r;
	r.cx=DeskRect.right-DeskRect.left;
	r.cy=DeskRect.bottom-DeskRect.top;
	size.cx=r.cx*80/1000;
	size.cy=r.cy*5/100;
	POINT p;
	p.y=r.cy*perbut;
	p.x=r.cx/2;
	StartButton->SetWindowPos(NULL,p.x-3*size.cx/2,p.y,size.cx,size.cy,NULL);
	PauseButton->SetWindowPos(NULL,p.x+size.cx/2,p.y,size.cx,size.cy,NULL);
	ASCButton->SetWindowPos(NULL,p.x-size.cx*7/2,p.y,size.cx,size.cy,NULL);
	DSCButton->SetWindowPos(NULL,p.x+size.cx*5/2,p.y,size.cx,size.cy,NULL);
	RandButton->SetWindowPos(NULL,p.x+size.cx*9/2,p.y,size.cx,size.cy,NULL);
	SettingButton->SetWindowPos(NULL,p.x-size.cx*11/2,p.y,size.cx,size.cy,NULL);
	BiggerButton->SetWindowPos(NULL,p.x-size.cx*3/2,p.y-size.cy*3/2,size.cx,size.cy,NULL);
	SmallerButton->SetWindowPos(NULL,p.x+size.cx*1/2,p.y-size.cy*3/2,size.cx,size.cy,NULL);
}

void SortWnd::OnSize(UINT nType, int cx, int cy) 
{
	CFrameWnd::OnSize(nType, cx, cy);
	
	DeskRect.bottom=cy;
	DeskRect.right=cx;
	SetButtonPos();
	int count=0;
	for (int i=0;i<MAX;i++)
		if (sort[i])
		{
			RECT r;
			this->SetRect(&r,count);
			sort[i]->SetRect(&r);
			count++;
		}
}

void SortWnd::OnASCButton()
{
	int NUM=Num_Data*Per_SC/100;
	int count=0;
	a=new int[Num_Data];
	srand(GetTickCount());
	for (int i=0;i<Num_Data;i++) a[i]=rand()%DataWidth+BaseData;
	for (i=0;i<NUM;i++) 
	{
		int k=rand()%Num_Data;
		while (a[k]==-1) k=rand()%Num_Data;
		a[k]=-1;
	}
	for (i=0;i<Num_Data;i++)
		if (a[i]==-1)
		{
			a[i]=BaseData+DataWidth*count/NUM;
			count++;
		}
	for (i=0;i<MAX;i++)
		if (sort[i])
		{
			sort[i]->SetTime(0);
			sort[i]->SetState2_3();
			sort[i]->SetData(a);
		}
	delete []a;
	Draw();

}

void SortWnd::OnDSCButton()
{
	int NUM=Num_Data*Per_SC/100;
	int count=0;
	srand(GetTickCount());
	a=new int[Num_Data];
	for (int i=0;i<Num_Data;i++) a[i]=rand()%DataWidth+BaseData;
	for (i=0;i<NUM;i++)
	{
		int k=rand()%Num_Data;
		while (a[k]==-1) k=rand()%Num_Data;
		a[k]=-1;
	}
	for (i=0;i<Num_Data;i++)
		if (a[i]==-1)
		{
			a[i]=BaseData+DataWidth*(NUM-count)/NUM;
			count++;
		}
	for (i=0;i<MAX;i++)
		if (sort[i])
		{
			sort[i]->SetTime(0);
			sort[i]->SetState2_3();
			sort[i]->SetData(a);
		}
	delete [] a;
	Draw();

}

void SortWnd::OnRandButton()
{
	a=new int[Num_Data];
	srand(GetTickCount());
	for (int i=0;i<Num_Data;i++) a[i]=rand()%DataWidth+BaseData;
	for (i=0;i<MAX;i++)
		if (sort[i])
		{
			sort[i]->SetTime(0);
			sort[i]->SetState2_3();
			sort[i]->SetData(a);
		}
	delete []a;
	Draw();
}

void SortWnd::EnableButtons(BOOL b)
{
	ASCButton->EnableWindow(b);
	DSCButton->EnableWindow(b);
	RandButton->EnableWindow(b);
	SettingButton->EnableWindow(b);
}

void SortWnd::OnSettingButton()
{
	dlg->ShowWindow(SW_SHOW);
}

void SortWnd::RandData()
{
	OnRandButton();
}

void SortWnd::Draw()
{
	for (int i=0;i<MAX;i++)
		if (sort[i])
			sort[i]->Draw();

}

void SortWnd::DrawFull()
{
	CClientDC dc(this); // device context for painting
	dc.BitBlt(0,0,DeskRect.right-DeskRect.left,(DeskRect.bottom-DeskRect.top)*persort,NULL,0,0,WHITENESS);
	Draw();
}

void SortWnd::OnSmallerButton()
{
	RECT r;
	this->GetWindowRect(&r);
	this->ClientToScreen(&r);
	int x=r.right-r.left;
	int y=r.bottom-r.top;
	this->SetWindowPos(NULL,0,0,x*3/4,y*3/4,NULL);
}

void SortWnd::OnBiggerButton()
{
	RECT r;
	this->GetWindowRect(&r);
	this->ClientToScreen(&r);
	int x=r.right-r.left;
	int y=r.bottom-r.top;
//	this->OnSize(NULL,x*4/3,y*4/3);
	this->SetWindowPos(NULL,0,0,x*4/3,y*4/3,NULL);

}

void SortWnd::DeleteThread()
{
	for (int i=0;i<MAX;i++)
		if (ThreadHandle[i]&&!sort[i])
		{
			TerminateThread(ThreadHandle[i],0);
			ThreadHandle[i]=0;
		}
}

void SortWnd::OnClose() 
{
	if (IsPaused) this->OnPauseButton();
	if (IsStarted) this->OnStartButton();	
	CFrameWnd::OnClose();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -