做了个职工管理系统,卡在排序那儿了,交换地址频频出错,只能改成交换数据域。。然而还是错的,求大神帮忙看看,谢谢!!!
头文件:
#include
#include
#include
#include
typedef struct worker{
char worker_number[10];
char worker_name[10];
char worker_sex[3];
char adm_number[5];
char position[10];
char major[20];
int salary;
char tel_number[20];
struct worker *next;
}worker;
#define null 0
int menu_select();
worker *input();
void display(struct worker *);
worker *add(struct worker *);
void account(struct worker *);
void total(struct worker *);
worker *delete_worker(worker *);
void bubble_sort(struct worker *);
void search(struct worker *);
排序函数:
#include "1.h"
void bubble_sort(struct worker *list)
{
int i,j,len=0;
worker *p1,*p2,*p3,*p4;
p2=(struct worker *)malloc(sizeof(worker));
p3=(struct worker *)malloc(sizeof(worker));
p4=(struct worker *)malloc(sizeof(worker));
p1=list->next;
p2=list->next;
p3=list->next->next;
p4=NULL;
while(p1)
{
p1=p1->next;
len++;
}
printf("有%d条记录!\n",len);
switch(len)
{
case 0:
printf("该表中无任何职工记录!\n");
break;
case 1:
printf("该表中只有1条记录!\n");
display(list);
break;
default :
for(i=0;i<len;i++)
{
for(j=0;j<len-1;j++)
{
if( p2->salary < p3->salary )
{
strcpy(p4->worker_number,p2->worker_number);
strcpy(p4->worker_name,p2->worker_name);
strcpy(p4->worker_sex,p2->worker_sex);
strcpy(p4->tel_number,p2->tel_number);
p4->salary=p2->salary;
strcpy(p4->position,p2->position);
strcpy(p4->major,p2->major);
strcpy(p4->adm_number,p2->adm_number);
strcpy(p2->worker_number,p3->worker_number);
strcpy(p2->worker_name,p3->worker_name);
strcpy(p2->worker_sex,p3->worker_sex);
strcpy(p2->tel_number,p3->tel_number);
p2->salary=p3->salary;
strcpy(p2->position,p3->position);
strcpy(p2->major,p3->major);
strcpy(p2->adm_number,p3->adm_number);
strcpy(p3->worker_number,p4->worker_number);
strcpy(p3->worker_name,p4->worker_name);
strcpy(p3->worker_sex,p4->worker_sex);
strcpy(p3->tel_number,p4->tel_number);
p3->salary=p4->salary;
strcpy(p3->position,p4->position);
strcpy(p3->major,p4->major);
strcpy(p3->adm_number,p4->adm_number);
}
p3=p3->next;
}
p2=p2->next;
}
printf("比较结束!\n");
display(list);
break;
}
}
补充下:
输入函数:带头结点的
#include "1.h"
worker *input()
{
int n=0;
worker *p1,*head,*tail,*p2;
head=(struct worker *)malloc(sizeof(worker));
if(head==NULL)
{
printf("分配是空间失败!\n");
exit(-1);
}
else
{
head->next=NULL;
printf("带有头结点的链表已建立!\n");
tail=head;
do
{
p1=(struct worker *)malloc(sizeof(worker));
if(p1==NULL)
{
printf("分配空间失败!\n");
exit(-1);
}
else
{
printf(" ----------------------------\n");
printf("| 二级部门相关信息如下 |\n");
printf("| 人事部 |\n");
printf("| 财务部 |\n");
printf("| 学工办 |\n");
printf("| 宣传部 |\n");
printf("| 教工部 |\n");
printf(" ----------------------------\n");
printf("当输入职工号为0时,输入结束!\n");
printf("请输入对应项目职工信息!\n");
printf("职工号:");
scanf("%s",p1->worker_number);
if(strcmp(p1->worker_number,"0")==0)
break;
else
{
p2=head;
while(p2)
{
if(strcmp(p2->worker_number,p1->worker_number)==0)
{
printf("\n该职工号:%s已存在,请重新输入!\n",p1->worker_number);
printf("职工号:");
scanf("%s",p1->worker_number);
if(strcmp(p1->worker_number,"0")==0)
goto loop;
}
else p2=p2->next;
}
}
printf("职工姓名:");
scanf("%s",p1->worker_name);
printf("职工性别:");
scanf("%s",p1->worker_sex);
printf("二级单位编号:");
scanf("%s",p1->adm_number );
printf("职工职称:");
scanf("%s",p1->position);
printf("职工所学专业:");
scanf("%s",p1->major);
printf("职工月工资:");
scanf("%d",&p1->salary);
printf("职工联系方式:");
scanf("%s",p1->tel_number);
getchar();
p1->next=NULL;
tail->next=p1;
tail=p1;
n++;
}
}while(strcmp(p1->worker_number,"0")>0);
loop: printf("\n职工信息输入结束,本次输入%d条记录!\n",n);
return (head);
}
}
/*
==========================
功能:直接插入排序(由小到大)
返回:指向链表表 头的指针
==========================
*/
/*
直接插入排序的基本思想就是假设链表的前面n-1个节点是已经按键值
(就是用它排序的字段,我们取学号num为键值)排好序的,对于节点n在
这个序列中找插入位置,使得n插入后新序列仍然有序。按照这种思想,依次
对链表从头到尾执行一遍,就可以使无序链表变为有序链表。
单向链表的直接插入排序图示:
---->[1]---->[3]----> [2]...---->[n]---->[NULL](原链表)
head 1->next 3->next 2->next n->next
---->[1]---->[NULL](从原链表中取第1个节点作为只有一个节点的有序链表)
head
图11
---->[3]---->[2]...---->[n]---->[NULL](原链表剩下用于直接插入排序的节点)
first 3->next 2->next n->next
图12
---->[1]---->[2]---->[3]...---->[n]---->[NULL](排序后链表)
head 1->next 2->next 3->next n->next
图13:有N个节点的链表直接插入排序
1、先在原链表中以第一个节点为一个有序链表,其余节点为待定节点。
2、从图12链表中取节点,到图11链表中定位插入。
3、上面图示虽说画了两条链表,其实只有一条链表。在排序中,实质只增加了一个用于指向剩下需要排序节点的头指针first罢了。
这一点请读者务必搞清楚,要不然就可能认为它和上面的选择排序法一样了。
*/
struct student *InsertSort(struct student *head)
{
struct student *first; /*为原链表剩下用于直接插入排序的节点头指针*/
struct student *t; /*临时指针变量:插入节点*/
struct student *p; /*临时指针变量*/
struct student *q; /*临时指针变量*/
first = head->next; /*原链表剩下用于直接插入排序的节点链表:可根据图12来理解。*/
head->next = NULL; /*只含有一个节点的链表的有序链表:可根据图11来理解。*/
while (first != NULL) /*遍历剩下无序的链表*/
{
/*注意:这里for语句就是体现直接插入排序思想的地方*/
for (t = first, q = head; ((q! = NULL) && (q->num < t->num)); p = q, q = q->next); /*无序节点在有序链表中找插入的位置*/
/*退出for循环,就是找到了插入的位置*/
/*注意:按道理来说,这句话可以放到下面注释了的那个位置也应该对的,但是就是不能。原因:你若理解了上面的第3条,就知道了。*/
first = first->next; /*无序链表中的节点离开,以便它插入到有序链表中。*/
if (q == head) /*插在第一个节点之前*/
{
head = t;
}
else /*p是q的前驱*/
{
p->next = t;
}
t->next = q; /*完成插入动作*/
/*first = first->next;*/
}
return head;
}
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。
提醒:再牛×的老师也无法代替学生自己领悟和上厕所!
单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。