看板Programming
标 题[问题] 结构‧档案‧链结串列
发信站交大资讯次世代BS2 (Thu Jan 26 03:42:54 2012)
转信站ptt!news.ntu!ctu-gate!ctu-peer!news.nctu!csnews.cs.nctu!news.cs.nctu!B
建立链结串列:
链结串列中,每个节点有两个成员,第一个成员用来存放资料,第二个成员用来储存指向下一个节点的指标,宣告方式如下:
struct node
{
int data;
struct node *next;
};
功能需求如下: 读取H5_1.txt,文件内容由整数与符号组成,数字以逗号(,)作为区隔,将数字存入链结串列中,由小到大排序串列中所有data成员(禁止使用QSRT函式)。1. 由H5_2.txt读取出的数字插入链结串列,仍须保持由小到大排序,将插入结果与串列内容写入H5_Add.txt;2. 插入後的链结串列中所有data成员出现在H5_3.txt则删除该成员,将删除後的串列内容写入H5_Del.txt。形式如下:
PS: H5_1.txt、H5_2.txt、H5_3.txt内容皆由整数与符号组成,此次作业禁止使用阵列,否则不给分。
范例:
H5_1.txt
2,1
H5_2.txt
3,4
H5_3.txt
1
H5_Add.txt
Data1:1
Data2:2
Data3:3
Data4:4
Node1: 22FEF0
Node2: 22FEF4
Node3: 22FEF8
Node4: 22FEFC
H5_Del.txt
Data1:2
Data2:3
Data3:4
Node1: 22FEF4
Node2: 22FEF8
Node3: 22FEFC
我想了很久以後写了下列的程式码,结果是可以成功印出H5_Add.txt,但是诡异的是每次印出来的位址都不一样,至於H5_Del.txt则是会删错数字,到底是哪里有问题?谁可以帮我看一下吗?
#include<stdio.h>
#include<stdlib.h>
struct node//定义结构node
{
int data;//资料成员
struct node *next;//链结成员,存放指向下一个节点的指标
};
typedef struct node NODE;//将struct node定义成NODE型态
NODE *INSERT,*first=NULL,*previous,*current;//宣告指向NODE型态的指标INSERT,first,previous,current,并将first设为起始指标
int main()
{
FILE *fptr1,*fptr2;//宣告指向档案的指标fptr1,fptr2
fptr1=fopen("H5_1.txt","r");//用fptr1指向H5_1.txt,开启H5_1.txt以供读取
fptr2=fopen("H5_2.txt","r");//用fptr2指向H5_2.txt,开启H5_2.txt以供读取
int n;//宣告整数变数n
char ch;//宣告字元变数ch
while(fscanf(fptr1,"%d%c",&n,&ch)!=EOF)//判断是否到达H5_1.txt的档尾
sortedinsert(n);//呼叫sortedinsert()函数
while(fscanf(fptr2,"%d%c",&n,&ch)!=EOF)//判断是否到达H5_2.txt的档尾
sortedinsert(n);//呼叫sortedinsert()函数
outputadd();//呼叫outputadd()函数,将H5_Add.txt的数字由小到大排列,并依照顺序印出数字位址
deletenode();//呼叫deletenode()函数
outputdel();//呼叫outputdel()函数,将H5_Del.txt的数字由小到大排列,并依照顺序印出数字位址
fclose(fptr1);//关闭H5_1.txt
fclose(fptr2);//关闭H5_2.txt
return 0;
}
void sortedinsert(int i)//sortedinsert()函数
{
INSERT=(NODE*)malloc(sizeof(NODE));//配置可存放NODE的记忆空间,并把INSERT指向它
INSERT->data=i;//将插入的data设为i
INSERT->next=NULL;//将插入的节点的下一个节点指向NULL
if(first==NULL)//如果第一个节点的值是NULL
first=INSERT;//将第一个节点指向插入的节点
else if((INSERT->data)<(first->data))//如果插入的data小於第一个data
{
INSERT->next=first;//将插入节点的下一个节点指向第一个节点
first=INSERT;//将第一个节点指向插入的节点
}
else//如果插入的data大於第一个data
{
previous=first;//将之前的节点指向第一个节点
current=first->next;//将现在的节点指向第一个节点的下一个节点
while(current!=NULL)//现在的节点不是NULL就执行以下回圈
{
if((INSERT->data)<(current->data))//如果插入的data小於现在的data
break;
else
{
previous=current;//将之前的节点指向现在的节点
current=current->next;//将现在的节点指向现在节点的下一个节点
}
}
INSERT->next=current;//将插入节点的下一个节点指向现在的节点
previous->next=INSERT;//将之前节点的下一个节点指向插入的节点
}
}
void outputadd()//outputadd()函数
{
FILE *fptradd;//宣告指向档案的指标fptradd
fptradd=fopen("H5_Add.txt","w");//用fptradd指向H5_Add.txt,开启H5_Add.txt以供写入
current=first;//将现在的节点指向第一个节点
int j=1;//宣告整数变数j,并将j的初始值设为1
while(current!=NULL)//现在的节点不是NULL就执行以下回圈
{
fprintf(fptradd,"Data%d:%d\n",j,current->data);//依序印出第j个data的值
j++;
current=current->next;//印完後就将现在的节点指向现在节点的下一个节点
}
current=first;//重新将之前的节点指向第一个节点
j=1;//重新将j的初始值设为1
while(current!=NULL)//现在的节点不是NULL就执行以下回圈
{
fprintf(fptradd,"Node%d:%p\n",j,current);//依序印出第j个data的位址
j++;
current=current->next;//印完後就将现在的节点指向现在节点的下一个节点
}
fclose(fptradd);//关闭H5_Add.txt
}
void deletenode(int m)//deletenode()函数
{
INSERT=(NODE*)malloc(sizeof(NODE));//配置可存放NODE的记忆空间,并把INSERT\
指向它
INSERT->data=m;//将插入的data设为m
INSERT->next=NULL;//将插入的节点的下一个节点指向NULL
if(first==NULL)//如果串列是空的
return NULL;//回传NULL
else if((INSERT->data)==(first->data))//如果插入的data等於第一个data
{
first=first->next;//将第一个节点指向下一个节点
INSERT->next=first->next;//将插入节点的下一个节点指向第一个节点的下一个节点
}
else
{
if(INSERT->next!=NULL)
previous->next=current->next;
else
previous->next=NULL;
}
free(INSERT);
}
void outputdel()//outputdel()函数
{
FILE *fptrdel;//宣告指向档案的指标fptrdel
fptrdel=fopen("H5_Del.txt","w");//用fptrdel指向H5_Del.txt,开启H5_Del.txt以供写入
current=first;//将现在的节点指向第一个节点
int k=1;//宣告整数变数k,并将k的初始值设为1
while(current!=NULL)//现在的节点不是NULL就执行以下回圈
{
fprintf(fptrdel,"Data%d:%d\n",k,current->data);//依序印出第k个data的值
k++;
current=current->next;//印完後就将现在的节点指向现在节点的下一个节点
}
current=first;//重新将之前的节点指向第一个节点
k=1;//重新将k的初始值设为1
while(current!=NULL)//现在的节点不是NULL就执行以下回圈
{
fprintf(fptrdel,"Node%d:%p\n",k,current);//依序印出第k个data的位址
k++;
current=current->next;//印完後就将现在的节点指向现在节点的下一个节点
}
fclose(fptrdel);//关闭H5_Del.txt
}
我的观念不熟,所以可能会有注解错误的地方,请各位高手不吝赐教!
--
※ Origin: 交大次世代(bs2.to)
◆ From: 218-160-191-13.dynamic.hinet.net