之前那个写的实在太长了,浏览器缩放简书的编辑器老是会出现预览错位的问题,所以另起一个文档开始写吧。
ps:希望两天能看完剩下这一点,老拖拉怪了。
3.2
首先是文本读写,不知道到底考不考
文本打开方式主要分为r,w,a,分别是只读(无对应文件返回空指针),只写(如果有对应文件则覆盖原文件,没有则创建新文件),插入(同无源文件下,创建新文件)三种方式,其中分别可以使用r+,w+,a+,以及利用 t 或者 b 后缀来扩充功能,tb则主要是选择文本方式还是二进制流打开,r+是可读可写,w+是构建可读可写新文件,a+则扩充了读写功能。
附带一提的是fopen函数两个参数都是const char* 字符串指针,所以第二个打开方式要用引号 “ ”。
3.4
int getc(FILE *fp)
int putc(int ch,FILE *fp)
这两个函数可以实现对文件的字符读入和写入,虽然使用的是整形的返回值和输入值,但是都只用低位字节表示字符。
值得一提的是:如果putc() 函数操作成功,则返回写入文件的字符ASCII码,若出现错误,则返回EOF,其值定义为-1,当阅读到文件结尾时,该函数返回一个EOF标记。
如果
getchar() getc(stdin)
putchar() putc(ch stdout)
下例输出文本内容
(前提要把txt文件实现设为ANSI格式 UTF-8会乱码)
(其实我也不是很清楚,反正改了就好了)
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char *s=malloc(sizeof(char)*10);
gets(s);
fp=fopen(s,"r");
char a;
if(fp==NULL)
{
puts("对不起,输出有点问题");
}
else
{
puts("成功打开文件");
}
while((a=getc(fp))!=EOF)
{
putchar(a);
}
}
稍微修改一下 就可以实现文件的复制了
int main()
{
FILE *fp,*fp2;
char *s=calloc(15,sizeof(char));
gets(s);
fp=fopen(s,"r+");
char a;
gets(s);
fp2=fopen(s,"w+");
if(fp==NULL)
{
puts("对不起,输出有点问题");
}
else
{
puts("成功打开文件");
}
while((a=getc(fp))!=EOF)
{
putchar(a);
putc(a,fp2);
}
}
char* fgets(char* p,int length,FILE* file)
int fputs(char*p,FILE *file) 注意这里是int 这本书错误还是不少的
fgets函数非常神奇,主要神奇就神奇在他的这个length上面。
假设length为3,当前行中字符数量超过3时,只会读入两个字符,因为剩下一个还要填充 “\0” ,同样,如果不超过length指定的长度,该字符串会将换行符读入到指定的字符数组中,剩下的空格用“\0”填充,这会产生许许多多莫名其妙的问题。
上面这段如果不理解的话,你可以理解为读入到字符数组p内的数据总是以 '\0' 结尾的,同时,换行符号会被认为是一个正常的输入字符被读入,这点与gets()函数有本质的区别。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp,*fp2;
char *s=calloc(15,sizeof(char));
gets(s);
fp=fopen(s,"r+");
gets(s);
fp2=fopen(s,"w+");
if(fp==NULL)
{
puts("对不起,输出有点问题");
}
else
{
puts("成功打开文件");
}
char a[1024];
while((fgets(a,7,fp)))
{
printf("%s %d\n",a,strlen(a));
fputs(a,fp2);
}
fgets(a,3,stdin); //用这两行测试一下就行了
puts(a);
}
下面是fwrite和fread
参数都蛮多
int fwrite(void *buffer,int size,int n,FILE *fp)
int fread(void *buffer,int size,int n,FILE *fp)
可以先讲一下返回值,返回值为实际读写的字符个数。
值得一提的是n是写入/读取的字符个数,而size指的是写入读出的字符大小。
然后是辅助的feof()和ferror() 函数,如果是空/错误就返回非零值,否则返回零值。
这两个东西通常都使用二进制的方式操作文件,从而实现对数组和结构体的读取和写入操作。
下面是示例代码:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct data
{
char name[10];
int year;
int month;
int day;
}student,*studentp;
int main()
{
puts("C:\\Users\\YFF\\Desktop\\ceshi\\chinese\\xinjian.txt");
student stus[3],stuscopy[3];
for(int i=0;i<3;i++)
{
scanf("%s %d %d %d",stus[i].name,&stus[i].year,&stus[i].month,&stus[i].day);
}
FILE* fp,rp;
fp=fopen("C:\\Users\\YFF\\Desktop\\ceshi\\chinese\\xinjian.txt","wb+"); //显式输入必须要转义符号
if(!fp) //不要忘记分号
{
printf("对不起错误");
return;
}
printf("%d",fwrite((void*)stus,sizeof(student),3,fp));
//这里写入完成
//我们开始读取
fclose(fp);
fp=fopen("C:\\Users\\YFF\\Desktop\\ceshi\\chinese\\xinjian.txt","rb"); //其实关不关都一样
fread((void*)stuscopy,sizeof(student),3,fp); //我也不知道为什么读三个不算到结尾,读四个才算到结尾
fgetc(fp);//使得EOF为真
if(feof(fp))
{
puts("已经到结尾");
}
for(int i=0;i<3;i++)
{
printf("%s %d %d %d\n",stuscopy[i].name,stuscopy[i].year,stuscopy[i].month,stuscopy[i].day);
}
}
用二进制方式而不是文本写入的txt文档几乎是不可读的,并不是说数据是无序的,只是我们手动打开并不能识别其中大部分的有效信息
int fseek(FILE* fp,int offset,int origin)
offset表示偏移量,origin表示起始位置。
要注意的是 origin形参的值只可以设置为 0 1 2 分别代表开头 当前位置 和 结尾,同时要注意的是默认偏移是向右
返回值很容易理解,操作成功返回0,失败返回非0值。
同样fseek通常适用于二进制方式打开文件。
fprintf
fscanf
这两个用法和scanf和printf几乎完全相同,只需要额外加上文件指针就OK,但是这种方法因为涉及到二进制数据向ASCII的转换以及逆向转换,会比较慢。
fseek应用实例
int main()
{
FILE* fp,rp;
fp=fopen("C:\\Users\\YFF\\Desktop\\ceshi\\chinese\\xinjian2.txt","rb+"); //显式输入必须要转义符号
if(!fp)
{
puts("打开文件失败");
}
fseek(fp,9,0);
printf("%c",getc(fp));;
}
文件的结尾EOF只有被读取后/传递后才会被检测到。
重提一下%c和%d的作用,前者用来忽视输入的字符(通常用来吃回车),后者需要两个数据来控制输出宽度和输出的字符。
练习题:
好像这部分不是什么重点,就不一道一道做了。
9.9 追加到末尾
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct data
{
char name[10];
int year;
int month;
int day;
}student,*studentp;
int main()
{
FILE *fp1,*fp2;
fp1=fopen("xinjian.txt","r");
fp2=fopen("xinjian2.txt","r+"); //将1的数据加到2的后面
if(!fp1||!fp2)
{
puts("打开失败");
}
fseek(fp2,0,2);//直接重定位到最后
//没什么用的小知识。如果使用a或者a+方式打开,则写入位置强制限定为末尾。
char get1;
while((get1=getc(fp1))!=EOF)
{
putchar(get1);
putc(get1,fp2);
}
fclose(fp1);
fclose(fp2);
}
这一章节就到这里吧,后面可能我会把王道群里面的题目以及数据结构部分的算法全部重写一遍,跟在这篇文章的下面。
真题:
int main()
{
int a[]={11,22};
int *p=a;
printf("%d\n",(*p++));
printf("%d",*p);
}
输出11,22,要注意的是p先执行++,但是p++返回值是11的地址,然后取11,输出11,此时p指向22,所以输出11,22。
震撼我一整年
void main()
{
int i=1;
switch(6)
{
printf("hello"); //这条语句永远都不会执行,因为他不在任何的case下
case 1:printf("Hi");
case 2:printf("Bye");
printf("hello"); //但是这条如果i的值为1或者为2会执行,为其他的值不会执行。
}
}
总而言之就是先找到对应的case,找不到就什么也不做。
这道题倒没什么,主要要记忆一下ASCII表,分别是0对应了48
A是65,a是97。
void main()
{
char c=48;
int i,mark=01;
for(i=0;i<5;i++)
{
printf("%c",c|mark);
mark=mark<<1;
}
}
要注意的是 *p.num这种东西
p为结构体指针时,由于运算优先级是4,所以先执行.再执行p
然后是老生常谈的&& ||运算优先级问题 遇到&&和||结合 先将&&两侧的统一括起来,然后依据从左往右计算原则计算即可。(即使左侧没有括号右侧有括号,那也是先算左边再算右边)
指针数组和数组指针
int* p[n] 指针数组
int (p)[n] 数组指针(行指针)
后者比较复杂 通常二维数组a[3][4] 就可以int (p)[4]=a; 从而p+1实现一行的地址跳跃
这里就提到老生常谈的问题了:
每次都要花费很长时间来理解这个东西,我建议在观看下面这个东西的时候,抛弃指针的概念,只要留下数组和数组名以及地址的概念就好了。
首先是 int a[3][4];
&a a &a[0] a[0] &a[0][0] a[0][0]
一共有六种数据表现形式,其中a和&a[0],a[0]与&a[0][0]是完全一样的,我们以一维数组举例,b[5],那么数组名代表数组首元素的地址,也就是b和&b[0] 完全等价,此处同理,这一个很好理解,那么我们只需要理解&a,&a[0],&a[0][0],a[0][0] (这个就不用解释了吧) 就好了,因为a等同于&a[0],a[0]等同于&a[0][0],由于&的运算优先级低于[],所以&a[0][0]就代表二维数组a的首元素的地址,数据类型是int*,而&a[0]代表二维数组a的首行元素的地址,数据类型是int (*)[4] (数组指针),而&a则代表整个二维数组的地址,数据类型是int (*)[3][4],总的简介就是这些,因此会有如下奇妙的式子:
int a[3][4] = { {1,2,3,4},
{5,6,7,8},
{9,10,11,12} };
int(*p)[4] = &a[0];
cout << p <<"---"<< *p << "---" <<**p<< endl;
cout << a[0] << "---" <<*(a[0]) << endl;
第一个cout输出的两个值完全相同,原因就在于,p是指向a的第一行地址,而*p则等于 等价于 *(&a[0]) 等价于*(a) 等价于 a[0] 等价于 &a[0][0] 也就是第一个元素的首地址,因此**p就可以输出第一个元素的值。
其实我觉得很多人对于这个东西存在误区就是没有真正的分清楚什么是数组指针,什么是指针指针,才会对这个问题有非常大的疑惑。
3.8
不是摸鱼了这么多天,我回去重新看了一下计算机网络,三天看了100多页这样子吧。
使用简单选择排序实现对链表的排序,讲道理,链表版还是挺复杂的。
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct linknode
{
int data;
struct linknode* next;
}linknode,*pnode;
void showLINK(pnode head);
pnode CreateLink(int sum)
{
pnode newp=calloc(1,sizeof(linknode));
newp->data=-1;
pnode temp=newp;
for(int i=0;i<sum;i++)
{
pnode newp2=calloc(1,sizeof(linknode));
temp->next=newp2;
scanf("%d",&newp2->data);
temp=newp2;
}
temp->next=NULL;
return newp;
}
pnode EASYsort(pnode head,int length)
{
pnode temp=head->next;
head->next=NULL;
while(temp!=NULL)
{
pnode maxnode=temp;
pnode premaxnode=NULL;
int max=temp->data;
pnode tp=temp;
pnode pre=NULL;
while(tp!=NULL)
{
if(tp->data>max)
{
max=tp->data;
maxnode=tp;
premaxnode=pre;
}
pre=tp;
tp=tp->next;
}
//到这里我们获得了最大值
//如果最大值是第一个元素 那么premax一定为NULL;
if(premaxnode==NULL)
{
temp=temp->next;
}
else
{
premaxnode->next=maxnode->next;
//否则temp保持不变 修改未排序链表配置
}
pnode headnext=head->next;
head->next=maxnode;
head->next->next=headnext;
showLINK(head);
}
}
void showLINK(pnode newp)
{
pnode temp=newp->next;
//检验链表是否构建正确
while(temp!=NULL)
{
printf("%4d",temp->data);
temp=temp->next;
}
puts("");
}
int main()
{
pnode newp=CreateLink(10);
//检验链表是否构建正确
showLINK(newp);
EASYsort(newp,10);
//简单选择排序
}
完美乘法:这道题确实不难
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//完美乘法,题目不明不白地
//如果只是判断a*b=c中要求abc中不可以有相同的数字,那还是挺简单的
void count(int data,int* p)
{
while(data)
{
p[data%10]+=1;
data/=10;
}
}
int main()
{
int a;
int b;
for(int i=1;i<99;i++)
{
for(int j=1;j<9999;j++)
{
a=i;
b=j;
int c=a*b;
int p[10]={0};
count(a,p);
count(b,p);
count(c,p);
bool flag=true;
for(int i=0;i<10;i++)
{
if(p[i]>1)
{
flag=false;
break;
}
}
if(flag)
{
printf("%d %d %d\n",a,b,c);
}
}
}
}
快速排序以及快速排序寻找第K小的元素
下面是快速排序代码
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//快速排序这种东西,关键就在你到底还记不记得是怎么写的。
void showdata(int* data,int length)
{
for(int i=0;i<length;i++)
{
printf("%4d",data[i]);
}
puts("");
}
void quickSort(int* data,int left,int right)
{
int nowd=data[left];
int templeft=left;
int tempright=right;
if(left<right)
{
while(left<right)
{
while(data[right]>nowd&&right>left)
{
right--;
}
data[left]=data[right];
while(data[left]<=nowd&&left<right)
{
left++;
}
data[right]=data[left];
}
data[left]=nowd;
showdata(data,15);
quickSort(data,templeft,left-1);
quickSort(data,left+1,tempright);
}
}
int main()
{
int a[15];
for(int i=0;i<15;i++)
{
scanf("%d",&a[i]);
}
quickSort(a,0,14);
}
额 人永远不会从过去的教训中获取什么教训,其实这句话原意是表示过去的经验不再适用于现在,表示了一种哲学上的观点,断章取义之后意思也改变了,不过这就不是我们讨论的内容了。
如果只是要找第K大的元素,那么并不需要对所有元素进行一次快速排序,只需要排序部分内容就可以了。
我依稀记得时间复杂度是O(n) (王道数据结构大概是这么说的)
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//快速排序这种东西,关键就在你到底还记不记得是怎么写的。
void showdata(int* data,int length)
{
for(int i=0;i<length;i++)
{
printf("%4d",data[i]);
}
puts("");
}
void quickSort(int* data,int left,int right)
{
int nowd=data[left];
int templeft=left;
int tempright=right;
if(left<right)
{
while(left<right)
{
while(data[right]>nowd&&right>left)
{
right--;
}
data[left]=data[right];
while(data[left]<=nowd&&left<right)
{
left++;
}
data[right]=data[left];
}
data[left]=nowd;
showdata(data,15);
quickSort(data,templeft,left-1);
quickSort(data,left+1,tempright);
}
}
void quickSortK(int* data,int left,int right,int k)
{
int nowp=data[left];
int templeft=left;
int tempright=right;
if(left<right)
{
while(left<right)
{
while(data[right]>nowp&&right>left)
{
right--;
}
data[left]=data[right];
while(data[left]<=nowp&&left<right)
{
left++;
}
data[right]=data[left];
}
data[left]=nowp;
showdata(data,15);
if(left==k)
{
printf("第%d大的元素是%d\n",k,data[k]);
}
else if(k<left)
{
quickSortK(data,templeft,left-1,k);
}
else
{
quickSortK(data,left+1,tempright,k);
}
}
}
int main()
{
int a[15];
for(int i=0;i<15;i++)
{
scanf("%d",&a[i]);
}
// quickSort(a,0,14);
puts("////////////////////////////////");
quickSortK(a,0,14,7); //这里的7表示的是排序好的a[7]
}
Joseph环问题,就是转一圈报数依次淘汰问题:
递归算法详细过程可看注释。
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//约瑟夫环问题
//似乎有巧妙的递归算法
//首先 每一轮都会淘汰一个倒霉鬼
//所以当前轮数人数为n,我们就将其成为n轮
//如果在第n轮中,一位同学的报数为k (k为0 1 2 3 4 5 6 m-1)
//之所以不从1开始是为了之后取余操作的方便
//因此如果在第n轮中报数为k,那么在n+1轮中他的编号应该是 (k+M)%(n+1) (编号从该轮报0的同学开始算)
//如果这位同学非常幸运混到了最后,只有一个人了,那他就是最后的胜利者 他应该报数0
//从而我们根据function(n+1)=(function(n)+M)%(n+1)来推算出 第一轮时,该同学的序号。
//我们为了递归方便,可修改递推公式为function(n)=(function(n-1)+M)%(n)
int Joseph(int n,int m)
{
if(n==1)
{
return 0;
}
else
{
return (Joseph(n-1,m)+m)%n;
}
}
//为了验证 我们又写了一个傻瓜函数
int Joseph_noob(int n,int m)
{
int* a=(int*)calloc(n,sizeof(int));
int count=0;
int saynumber=0;
int point=0;
while(count!=n-1)
{
if(a[point]==0)
{
saynumber++;
if(saynumber==m)
{
saynumber=0;
a[point]=1;
count++;
}
}
point=(point+1)%n;
}
for(int i=0;i<n;i++)
{
if(a[i]==0)
{
printf("%d",i);
}
}
puts(" ");
free(a);
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
printf("%d\n",Joseph(n,m));
Joseph_noob(n,m);
}
3.10
输入x和n 求sum
sum=1+x-x^2 /2!+x^3 /3!-……+(-1)^(n+1) x^n/n!
easy 没什么好说的
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//sum=1+x-x^2/2!+x^3/3!-……+(-1)^(n+1)x^n/n!
int main()
{
int num;
int x;
scanf("%d %d",&num,&x);
float sum=1;
float temp=-1;
for(int i=1;i<=num;i++)//sorry
{
temp=temp*x*(-1.0)/i; //第一次表示 x/1
//第二次为x * -1 *x /2 即为-x^2 /2
//第三次明显为 x^3 / 6
printf("%f\n",temp);
sum+=temp;
}
printf("%f",sum);
}
大杂烩。求质因数、删除字符串中的英文和数字并将重复字符减为一个、约瑟夫环、链表逆序。
求质因数:
辗转相除法 pass
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//求质因数、删除字符串中的英文和
//数字并将重复字符减为一个、约瑟夫环、链表逆序。
int function_1(int a,int b)
{
int big,small;
big=a>b?a:b;
small=a<b?a:b;
while(big>small)
{
int temp;
temp=big%small;
if(temp==0)
{
printf("最大公因数是%d\n",small);
break;
}
else
{
big=small;
small=temp;
}
}
return small;
}
void function_2(int a,int b)
{
int GongYinZi=function_1(a,b);
printf("%d",a*b/GongYinZi);
}
int main()
{
int a,b;
scanf("%d %d",&a,&b);
function_1(a,b);
function_2(a,b);
}
删除特定字符并且减少重复字符为1个 (我的理解是黄迪明书上的减少连续的重复字符,否则的话我建议手动构建哈希表)
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//求质因数、删除字符串中的英文和
//数字并将重复字符减为一个、约瑟夫环、链表逆序。
//输入字符务必注意不要输入中文的标点符号,会造成意外的bug
char* function(char* string)
{
int length=strlen(string);
char pre=0;
char now=0;
int nownumber;
int deletenumber;
for(int i=0;i<length;i++)
{
if((string[i]>='a'&&string[i]<='z')||(string[i]>='A'&&string[i]<='Z')||(string[i]>='0'&&string[i]<='9'))
{
//如果是数字或者是字母
deletenumber++;
pre=0;
//我们只将deletenumber++;
}
else
{
if(pre==string[i])
{
deletenumber++;
}
else
{
string[i-deletenumber]=string[i];
pre=string[i];
putchar(string[i]);
puts("");
}
}
}
//即最后一个有效输入必然是length-deletenumber-1的位置
string[length-deletenumber]='\0';
return string;
}
int main()
{
char* p=malloc(sizeof(char)*50);
gets(p);
puts(p);
puts("--------------------这是一条分割线-------------------");
puts(function(p));
}
约瑟夫环省略,此处只列出链表逆置
同样没什么难度
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//求质因数、删除字符串中的英文和
//数字并将重复字符减为一个、约瑟夫环、链表逆序。
typedef struct linknode
{
int data;
struct linknode* next;
}linknode,*pnode;
void showLINK(pnode head);
pnode CreateLink(int sum)
{
pnode newp=calloc(1,sizeof(linknode));
newp->data=-1;
pnode temp=newp;
for(int i=0;i<sum;i++)
{
pnode newp2=calloc(1,sizeof(linknode));
temp->next=newp2;
scanf("%d",&newp2->data);
temp=newp2;
}
temp->next=NULL;
return newp;
}
void showLINK(pnode newp)
{
pnode temp=newp->next;
//检验链表是否构建正确
while(temp!=NULL)
{
printf("%4d",temp->data);
temp=temp->next;
}
puts("");
}
pnode function(pnode head)
{
pnode thead=head->next;
head->next=NULL;
while(thead!=NULL)
{
pnode temp2=thead->next;; //注意这里在移动thead之前要保存他之后的节点 防止断链
thead->next=head->next;
head->next=thead;
thead=temp2;
}
return head;
}
int main()
{
pnode newp=CreateLink(10);
//检验链表是否构建正确
showLINK(newp);
//简单选择排序
showLINK(function(newp));
}
阅读下面的代码,说出输出结果
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//求质因数、删除字符串中的英文和
//数字并将重复字符减为一个、约瑟夫环、链表逆序。
void swap(char* a,char* b)
{
char temp[30];
strcpy(temp,a);
strcpy(a,b);
strcpy(b,temp);
}
int main()
{
char ceshi[][30]={"v","a","d","e","f"};
int n=5;
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<=n-1;j++)
{
if(ceshi[i]>ceshi[j])
{
puts("....");
swap(ceshi[i],ceshi[j]);
}
}
}
for(int i=0;i<n;i++)
{
puts(ceshi[i]);
}
}
如果if里面是像我这样写的,输出结果和原字符串数组不会有任何改变,因为字符串的直接比较,是地址大小的比较,如果修改为 strcmp 则 会变为从小到大的字符串排序。
删除str1中所有和str2中相同的字符
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//删除str1 中str2中出现过的字符
void main()
{
//这个东西其实和删除指定字符没什么区别,要求用指针实现
//EASY
char* str1=calloc(30,sizeof(char));
char* str2=calloc(30,sizeof(char));
gets(str1);
gets(str2);
int length1=strlen(str1);
int length2=strlen(str2);
int deletenum;
for(int i=0;i<length1;i++)
{
bool flag=true;
for(int j=0;j<length2;j++)
{
if(str1[i]==str2[j])
{
deletenum++;
flag=false;
break;
}
}
if(flag) //表明没有被删除
{
str1[i-deletenum]=str1[i];
}
}
str1[length1-deletenum]='\0';
puts("-----------我是分割线-------------");
puts(str1);
}
逆置链表的另外一种方式,凭依着除链表头的第一个节点,依次实现逆置:
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
//链表逆序。
typedef struct linknode
{
int data;
struct linknode* next;
}linknode,*pnode;
void showLINK(pnode head);
pnode CreateLink(int sum)
{
pnode newp=calloc(1,sizeof(linknode));
newp->data=-1;
pnode temp=newp;
for(int i=0;i<sum;i++)
{
pnode newp2=calloc(1,sizeof(linknode));
temp->next=newp2;
scanf("%d",&newp2->data);
temp=newp2;
}
temp->next=NULL;
return newp;
}
void showLINK(pnode newp)
{
pnode temp=newp->next;
//检验链表是否构建正确
while(temp!=NULL)
{
printf("%4d",temp->data);
temp=temp->next;
}
puts("");
}
pnode function(pnode head)
{
pnode newhead=head->next;
pnode select;
while(newhead->next!=NULL)
{
select=newhead->next;
newhead->next=select->next;
select->next=head->next;
head->next=select;
showLINK(head);
}
return head;
}
int main()
{
pnode newp=CreateLink(10);
//检验链表是否构建正确
showLINK(newp);
//简单选择排序
showLINK(function(newp));
}