c 链表排序 - 选择排序

面试题: 


有一个文件(名为a.txt)如下,每行有4项,第一项是他们的名次,写一个c程序,将五个人的名字打印出来.并按名次排序后将5行数据仍然保存到a.txt中.使文件按名次排列每行.

2 07010188 0711 李镇豪,

1 07010154 0421 陈亦良,

3 07010194 0312 凌瑞松,

4 07010209 0351 罗安祥,

5 07010237 0961 黄世传,

#include "stdafx.h"
#include <iostream>
using namespace std;
struct MyStruct
{
	int   store;
	char data[200];
	char sex[20];
	char name[20];
	MyStruct *pNext;
	///*2,07010188,0711,李镇豪,
	//	1,07010154,0421,陈亦良,
	//	3,07010194,0312,凌瑞松,
	//	4,07010209,0351,罗安祥,
	//	5,07010237,0961,黄世传,*/

};


MyStruct* CreateList();
MyStruct* SortList(MyStruct *pHead);

int main()
{
	MyStruct *pHead = NULL;
	pHead = CreateList();

	MyStruct* pAfterSortList;
	cout<<"排序之后的成绩单为"<<endl;
	pAfterSortList = SortList(pHead);
	while(pAfterSortList != NULL)
	{
		cout<<"-------------------------------------"<<endl;
		cout<<"store= "<<pAfterSortList->store<<"\n"\
			<<"name= "<<pAfterSortList->name<<"\n"\
			<<"data= "<<pAfterSortList->data<<"\n"\
			<<"sex= "<<pAfterSortList->sex<<""<<endl;
		pAfterSortList = pAfterSortList->pNext;
	}
	system("pause");
}
//查找最小的数据
MyStruct* FindMidStroe(MyStruct* pHead)
{
	MyStruct *pBegin = pHead;
	MyStruct *pNode = NULL;

	int nMin = pHead->store;
	while(pBegin != NULL)
	{
		if(pBegin->store < nMin)
		{
			nMin = pBegin->store;
			pNode = pBegin;
		}
		pBegin = pBegin->pNext;
	}

	if(pNode == NULL)//说明头就是最小的数据
	{
		return pHead;
	}

	//把最小节点放到头

	int   nStore = pNode->store;
    char *data = pNode->data;
	char *sex  = pNode->sex;
	char *name = pNode->name;

	pNode->store = pHead->store;
	strcpy(pNode->data,pHead->data);
	strcpy(pNode->name, pHead->name);
	strcpy(pNode->sex , pHead->sex);


	pHead->store = nStore;
	strcpy(pHead->data,data);
	strcpy(pHead->name, name);
	strcpy(pHead->sex , sex);

	return pHead;
}

MyStruct* SortList(MyStruct *pValue)
{
	//选择排序,先找到最大的或者最小的放入到另一个相同类型的序列中
	MyStruct *pHead = NULL;
	MyStruct *pData = NULL;
	while(1)
	{
		pValue = FindMidStroe(pValue);	//返回值
		
		MyStruct *pTemp = new MyStruct;
		strcpy(pTemp->data, pValue->data);
		strcpy(pTemp->name, pValue->name);
		strcpy(pTemp->sex, pValue->sex);
		pTemp->store = pValue->store;
		pTemp->pNext = NULL;

		if(pHead == NULL)
		{
			pHead = pTemp;
			pData = pHead;
		}
		else
		{
			pData->pNext = pTemp;
			pData = pTemp;
		}

		if((pValue = pValue->pNext) == NULL) break;
	}
	return pHead;
}

MyStruct* CreateList()
{

	MyStruct *pHead = NULL;
	MyStruct *pData = NULL;
	FILE* file = fopen("a.txt", "r");
	while(1)
	{
		MyStruct *pTemp= new MyStruct;
		if(fscanf(file, "%d%s%s%s",&pTemp->store, pTemp->data, pTemp->sex, pTemp->name) == -1) break;
		pTemp->pNext = NULL;
		if(pHead == NULL)
		{
			pHead = pTemp;
			pData = pHead;
		}
		else
		{
			pData->pNext = pTemp;
			pData = pTemp;
		}
	}

	return pHead;
}


2016-3-20 日更新。看了别人写的链表的排序算法,感觉自己写的真的很不好。第一个思路方面都不达标。所以粘贴其他人的代码供大家和自己欣赏

/********************************* 链表的排序  *******************************************/
/*
==========================
 功能:选择排序(由小到大)
 返回:指向链表表头的指针
==========================

1、先在原链表中找最小的,找到一个后就把它放到另一个空的链表中;
2、空链表中安放第一个进来的节点,产生一个有序链表,并且让它在原链表中分离出来(此时要注意原链表中出来的是第一个节点还是中间其它节点);
3、继续在原链表中找下一个最小的,找到后把它放入有序链表的尾指针的next,然后它变成其尾指针;
*/
struct student *SelectSort(struct student *head)
{
    struct student *pfirst;      /* 排列后有序链的表头指针 */
    struct student *ptail;       /* 排列后有序链的表尾指针 */
    struct student *pminBefore;  /* 保留键值更小的节点的前驱节点的指针 */
    struct student *pmin;        /* 存储最小节点   */
    struct student *p;           /* 当前比较的节点 */
 
    pfirst = NULL;
    while (head != NULL)         /*在链表中找键值最小的节点。*/
    {
    /* 注意:这里for语句就是体现选择排序思想的地方 */
        for (p = head, pmin = head; p->next != NULL; p = p->next) /*循环遍历链表中的节点,找出此时最小的节点。*/
        {
            if (p->next->num < pmin->num) /*找到一个比当前min小的节点。*/
            {
                pminBefore = p;           /*保存找到节点的前驱节点:显然p->next的前驱节点是p。*/
                pmin       = p->next;     /*保存键值更小的节点。*/
            }
        }
  
    /*上面for语句结束后,就要做两件事;一是把它放入有序链表中;二是根据相应的条件判断,安排它离开原来的链表。*/
    
        /*第一件事*/
        if (pfirst == NULL)     /* 如果有序链表目前还是一个空链表                      */
        {
            pfirst = pmin;      /* 第一次找到键值最小的节点。                          */
            ptail  = pmin;      /* 注意:尾指针让它指向最后的一个节点。                */
        }
        else                    /* 有序链表中已经有节点                                */
        {
            ptail->next = pmin; /* 把刚找到的最小节点放到最后,即让尾指针的next指向它。*/
            ptail = pmin;       /* 尾指针也要指向它。                                  */
        }

        /*第二件事*/
        if (pmin == head)        /* 如果找到的最小节点就是第一个节点                    */
        {
            head = head->next;   /* 显然让head指向原head->next,即第二个节点,就OK       */
        }
        else /*如果不是第一个节点*/
        {
            pminBefore->next = pmin->next; /*前次最小节点的next指向当前pmin的next,这样就让pmin离开了原链表。*/
        }
    }

    if (pfirst != NULL)     /*循环结束得到有序链表first                */
    {
        ptail->next = NULL; /*单向链表的最后一个节点的next应该指向NULL */ 
    }
    head = pfirst;
    return head;
}


写的不怎么好,如果有问题或者逻辑思路不怎么好,欢迎大家给我留言。您的留言是我进步的动力

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码i小学生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值