//insert "OL" into Order_Linear_List @ "i"
创新互联主要从事成都网站设计、做网站、成都外贸网站建设公司、网页设计、企业做网站、公司建网站等业务。立足成都服务浑南,10年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18982081108
Status ListInsert_OL(Order_Linear_List L , int i , Order_Linear_List OL){
cout"this function begain to run ...\n";
//check the "i" illegal or not
if(i1 || iL.length) return ERROR ;
//realloc the RAM when the previous storage space is full ...
if(L.length = L.listSize){
Order_Linear_List * newBaseAdd ;
newBaseAdd = (Order_Linear_List *)realloc(L.listBase,(L.listSize+LIST_INCREAMENT)*sizeof(Order_Linear_List));
if(!newBaseAdd)return(OVERFLOW);
L.listBase = newBaseAdd ;
L.listSize += LIST_INCREAMENT ;
}
//get the index of where to insert the element
Order_Linear_List *q ;
q = L.listBase[i-1];
//move the element behand of the insert-index
Order_Linear_List *p ;
for (p = L.listBase[L.length-1] ; p = q ; --p) *(p+1) = *p ;
*q = OL ;
L.length += 1;
return OK ;
}
常用词汇:
1、short:修饰int,短整型数据,可省略被修饰的int。
2、long:修饰int,长整型数据,可省略被修饰的int。
3、long long:修饰int,超长整型数据,可省略被修饰的int。
4、signed:修饰整型数据,有符号数据类型。
5、unsigned:修饰整型数据,无符号数据类型。
6、restrict:用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式。
7、return:用在函数体中,返回特定值(如果是void类型,则不返回函数值)。
8、continue:结束当前循环,开始下一轮循环。
9、break:跳出当前循环或switch结构。
10、goto:无条件跳转语句。
11、if:条件语句,后面不需要放分号。
12、else:条件语句否定分支(与if连用)。
13、switch:开关语句(多重分支语句)。
14、case:开关语句中的分支标记,与switch连用。
15、default:开关语句中的“其他”分支,可选。
常用函数:
1、int isalpha(int ch) 若ch是字母('A'-'Z','a'-'z'),返回非0值,否则返回0。
2、int isalnum(int ch) 若ch是字母('A'-'Z','a'-'z')或数字('0'-'9'),返回非0值,否则返回0。
3、int abs(int i) 返回整型参数i的绝对值。
4、double cabs(struct complex znum) 返回复数znum的绝对值。
5、double fabs(double x) 返回双精度参数x的绝对值。
6、long labs(long n) 返回长整型参数n的绝对值。
参考资料来源:百度百科—C语言
1、添加头文件"stdio.h"
2、struct student * creat(void),但是你的main函数中返回接收却是用的int*类型。
3、主函数main应当明确声明为void main()
4、最为严重的是:struct student * creat(void) 函数体中使用了局部变量struct student *head; struct student *p1,*p2; 但是函数结束的地方却要返回这些指针,因此返回的值是无效数据。返回时,已经不再作用域了,是无效的空间。建议把这些数据当作输入参数,指针类型的。就可以正确的接收分配的struct student空间以及指针了。
5、struct student * creat(void) 函数体中,临时指针*p1、*p2再函数返回之前应当设置为NULL,避免因为局部变量的作用域结束导致相关的空间被清除。
总之,我建议把struct student * creat(void)定义修改为:
void creat(struct student **head).
以上内容经过调试,可以使用。
==================我的程序,经过完整的调试
#include "stdafx.h"
#include "malloc.h"
#include "stdio.h"
#define NULL 0
#define LEN sizeof(struct student)
struct student
{
long num;
float score;
struct student *next;
};
int n;
void creat(struct student **head) /*定义函数,此函数带回一个指向链表头的指针*/
{
struct student *p1,*p2;
n=0;
do
{
p1=(struct student *)malloc(LEN); /*开辟一个新单元*/
p1-next=NULL;
scanf("%ld,%f",p1-num,p1-score);
if(p1-num==0)
break;
n++;
if(n==1)
*head=p1;
else
p2-next=p1;
p2=p1;
} while(p1-num!=0) ;
p1=NULL;
p2=NULL;
}
void main()
{
struct student *p;
creat(p);
if(p!=NULL)
do
{
printf("%ld %5.1f\n",p-num,p-score);
p=p-next;
}while(p!=NULL);
flushall(); //清除键盘缓冲区,避免输入混淆
getchar(); //等待键盘任意输入,以便观察运算结果
}
看我的回答怎么样?
答案:
①p0
②p1
③NULL
解析:
p0指向要插入的结点,p1指向要和p0结点的info进行比较的结点,如果找到应该插入的位置,p0会被插入在p1之前,如果没找到,会被插入在p1之后。
第一个if检查链表是否为空,如果为空,直接将p0变为首结点就完成了插入。
while循环的作用是寻找插入位置,因为链表要求降序,所以用p1从首结点开始找,要找到第一个info小于等于p0结点的结点。每次循环结束后,p2将指向p1之前的结点,为后面的插入作准备。
第二个if检查之前的while循环是否找到这样的结点。如果没找到,说明前面从while循环出来时p1指向的是尾结点,这时要将p0插入到链表末尾,所以将p0插入到p1之后。p0的后面没有结点,所以它的link指向NULL,所以第③问填NULL。如果找到了,那么进入第三个if。
第三个if检查p1是否刚好为首结点,如果为首结点,说明前的while循环根本没进去直接就出来了,这时p1之前没有结点,p2还没有指向任何结点,所以还不能使用p2。由于要将p0插入到p1之前,所以必须将p0变为首结点,所以第①问填p0。
如果p1不是首结点,进行的就是常规的插入操作了,将p0插入到p1之前,p2之后,所以第②问填p1。注意这里不能填p2-link,因为这里不在第三个if的else里面,第三个if出来以后也要经过这一步,而之前说了,如果进入了第三个if,p2是不能使用的。
单链表的插入呀
for的意思是先创建一个空节点,p指向它,然后你输入一个元素,把这个元素放到这个节点的info域,即scanf(“%c”,p-info),这句应该在printf后面,你掉了
然后把这个p赋值给q的next域,应该是q-next=p;你写错了,即头节点指向下一个节点了
之后q=p;是让q指向这个新节点,继续循环。
正确代码:
for(i=1;in;i++)
{
p=(NODE*)malloc(sizeof(NODE));
printf("Enter a element\n");
scanf(“%c”,p-info);
q-next=p;
q=p;
}
#includestdio.h#includewindows.h#include stdio.h#include malloc.h#include stdlib.h//定义数据类型名称typedef int DataType;#define flag -1 //定义数据输入结束的标志数据//单链表结点存储结构定义typedef struct Node{ DataType data; struct Node *next;}LNode ,*LinkList;//建立单链表子函数 LNode *Create_LinkList(){ LNode *s,*head,*L;int i=0,x; //定义指向当前插入元素的指针 while(1) { scanf("%d",x); if(-1==x) { return head; break;} s= (LNode *)malloc(sizeof(LNode)); //为当前插入元素的指针分配地址空间 s-data =x; s-next =NULL; i++; if(i==1) head=s; else L-next =s; L=s; }}//查找子函数(按序号查找)LNode *Get_LinkList(LinkList L,int i){ LNode *p; int j; //j是计数器,用来判断当前的结点是否是第i个结点 p=L; j=1; while(p!=NULLji) { p=p-next ; //当前结点p不是第i个且p非空,则p移向下一个结点 j++; } return p;}//插入运算子函数void Insert_LinkList(LinkList L,int i,DataType x) //在单链表L中第i个位置插入值为x的新结点{ LNode *p,*s; p =Get_LinkList(L,i); //寻找链表的第i-1个位置结点 if(p==NULL) { printf("插入位置不合法!"); exit(-1); } else { s= (LinkList)malloc(sizeof(LNode)); //为当前插入元素的指针分配地址空间 s-data =x; s-next =p-next ; p-next =s; }}//单链表的删除运算子函数void Delete_LinkList(LinkList L,int i) //删除单链表上的第i个结点{ LNode *p,*q; p=Get_LinkList(L,i-1); //寻找链表的第i-1个位置结点 if(p==NULL) { printf("删除的位置不合法!"); //第i个结点的前驱结点不存在,不能执行删除操作 exit(-1); } else { if(p-next ==NULL) { printf("删除的位置不合法!"); //第i个结点不存在,不能执行删除操作 exit(-1); } else { q=p-next ; p-next =p-next-next; free(q); } }}//求表长运算子函数int Length_LinkList(LinkList L){ int l; //l记录L的表长 LNode *p; p=L; l=1; while(p-next) { p=p-next; l++; } return l;}int main (){ LNode *head,*p; head=(LinkList)malloc(sizeof(LNode)); int x,y; a: printf("*******menu*******\n"); printf("**创建**********1*\n"); printf("**插入**********2*\n"); printf("**删除**********3*\n"); printf("**表长**********4*\n"); printf("**清屏**********5*\n"); printf("**打印**********6*\n"); printf("**退出******other*\n"); printf("******************\n"); int i=1; while(i) { printf("请输入选项:"); scanf("%d",i); switch(i) { case 1:head=Create_LinkList(); getchar();break; case 2:printf("请输入位置和数据;"); scanf("%d%d",x,y); Insert_LinkList(head,x,y);break; case 3:printf("请输入位置;"); scanf("%d",x); Delete_LinkList(head,x);break; case 4:printf("%d",Length_LinkList(head));break; case 5:system("cls");goto a; case 6:p=head; while(p!=NULL) {printf("%d\n",p-data); p=p-next;} break; default :i=0; } }}
我把创建给改了一下