大佬博客传送门 个人理解
p:我是当前指针,我喜欢不断的指向新的未知。
q:我是上一个指针(也就是以前的p),我来指向当前的指针
(接替p的位置),好让当前的指针(p)去指向下一个未知。
k:我是不断被动态开辟的空间,我每次开辟,p就会来指向我,
假设我用编号来表示空间(假设)那么我从1->2->3不断的被开辟链接,
是q将每次新开辟的空间连在了一起。
中二一下
茫茫的星空,q的下一步不知道该怎么走,于是q->next毫无着落,这时。p来了,p:我来当你的下一步吧。于是,p舍身取义的担当了q的下一步(q->next = p)。q很感动,对p说,我来成为你(q = p)吧,你去拯救更多的我。于是薪火相传,薪火不灭,茫茫宇宙,架起了一座桥,它的名字叫——链表。
using namespace std;
struct node{
int data;
struct node *next;//这里的struct是可以略去的。*next表示指向下一个结构体的指针。
};
int main()
{
struct node *head,*p,*q,*t;//定义指针的类型/ p 代表临时指针
int i,n,a;
cin>>n;
head=NULL;
for(int i=1;i<=n;i++)
{
cin>>a;
p=(struct node *)malloc(sizeof(struct node));//动态申请一个空间,用来存放一个节点,并用临时指针last指向这个结点
//malloc(sizeof(int))
//last=(int *)malloc(sizeof(int));
//*p=10;
p->data=a;//存储当前的数据
p->next=NULL;//当前的节点后继为空(当前节点的下一个为空)
if(head==NULL)
head=p;//第一个创建的节点,则将头指针指向这个节点。
else
q->next=p;//上一个节点的后继指针指向当前的节点。
//这是分开的
q=p;//指针也指向当前节点。
}
cin>>a;
t=head;
while(t!=NULL)
{
if(t->next==NULL||t->next->data>a)
{
p=(struct node *)malloc(sizeof(struct node));
p->data=a;
p->next=t->next;
t->next=p;
break;
}
t=t->next;
}
t=head;
while(t!=NULL)
{
cout<<t->data<<' ';
t=t->next;
}
return 0;
}
struct slist
{ double s;
struct slist *next;
};
typedef struct slist STREC;
//..............................
double fun( STREC *h )
{
double sum=0.0;
int count=0;
/*指针类型*/STREC *p=h->next;//定义结构体指针类型//已知h指向头结点,使p指向下一节点
if(p==NULL)
return sum;
while(p)
{
sum+=p->s;
p=p->next;
count++;
}
return sum/count;
}
//.............................*
STREC * creat( double *s)
{ STREC *h,*p,*q; int i=0;
h=p=(STREC*)malloc(sizeof(STREC));p->s=0;
while(i<N)
{ q=(STREC*)malloc(sizeof(STREC));
q->s=s[i]; i++; p->next=q; p=q;
}
p->next=0;
return h;
}
void outlist( STREC *h)
{ STREC *p;
p=h->next; printf("head");
do
{ printf("->%4.1f",p->s);p=p->next;}
while(p!=0);
printf("\n\n");
}
void main()
{ double s[N]={85,76,69,85,91,72,64,87},ave;
void NONO ( );
STREC *h;
h=creat( s ); outlist(h);
ave=fun( h );
printf("ave= %6.3f\n",ave);
NONO();
}
void NONO()
{/* 本函数用于打开文件,输入数据,调用函数,输出数据,关闭文件。 */
FILE *in, *out ;
int i,j ; double s[N],ave;
STREC *h ;
in = fopen("in.dat","r") ;
out = fopen("out.dat","w") ;
for(i = 0 ; i < 10 ; i++) {
for(j=0 ; j < N; j++) fscanf(in, "%lf,", &s[j]) ;
h=creat( s );
ave=fun( h );
fprintf(out, "%6.3lf\n", ave) ;
}
fclose(in) ;
fclose(out) ;
}
更新
建立单向链表的一般步骤:
建立一个头指针->建立第一个结点->头指针指向第一个结点->建立第二个结点->第一个结点的指针指向第二个结点->.......->最后一个结点的指针指向NULL。
向链表中插入一个元素,使原来顺序不变。
核心代码
t = head;
cin>>a;
while(t!=NULL)
{
if(t->next==NULL||t->next->s>a)
{
p=(struct node*)malloc(sizeof(struct node));
p->s=a;
p->next=t->next;//新增节点的后继指针指向当前节点的后继指针所指向的节点。
t->next=p;//将当前节点后继指针所指向的节点改为新增节点。
break;
}
t=t->next;
}
全部代码
using namespace std;
const ll maxn = 100 + 5;
//ll a[maxn],b[maxn];
bool vis[maxn][maxn];
string a[maxn];
int n, m;
struct node {
int s;
struct node *next;
};
int main() {
int n;
cin >> n;
struct node *q, *p, *head, *t;
head = NULL;
int a;
for(int i = 0; i < n; i++) {
cin >> a;
p = (struct node*)malloc(sizeof(struct node));
p->s = a;
p->next = NULL;
if(head == NULL)
head = p;
else {
q->next = p;
}
q=p;
}
t = head;
cin>>a;
while(t!=NULL)
{
if(t->next==NULL||t->next->s>a)
{
p=(struct node*)malloc(sizeof(struct node));
p->s=a;
p->next=t->next;//新增节点的后继指针指向当前节点的后继指针所指向的节点。
t->next=p;//将当前节点后继指针所指向的节点改为新增节点。
break;
}
t=t->next;
}
t=head;
while(t!=NULL)
{
cout<<t->s<<' ';
t=t->next;
}
return 0;
}
更新代码核心:
void fun( SLIST *p)
{ SLIST *t, *s;
t=p->next; s=p;
while(t->next != NULL)
{ s=t;
/**********found**********/
t=t->next;
}
/**********found**********/
printf(" %d ",t->data);
s->next=NULL;
/**********found**********/
free(t);
}
代码
typedef struct list
{ int data;
struct list *next;
} SLIST;
........................................
void fun( SLIST *p)
{ SLIST *t, *s;
t=p->next; s=p;
while(t->next != NULL)
{ s=t;
/**********found**********/
t=t->next;
}
/**********found**********/
printf(" %d ",t->data);
s->next=NULL;
/**********found**********/
free(t);
}
........................................
SLIST *creatlist(int *a)
{ SLIST *h,*p,*q; int i;
h=p=(SLIST *)malloc(sizeof(SLIST));
for(i=0; i<N; i++)
{ q=(SLIST *)malloc(sizeof(SLIST));
q->data=a[i]; p->next=q; p=q;
}
p->next=0;
return h;
}
void outlist(SLIST *h)
{ SLIST *p;
p=h->next;
if (p==NULL) printf("\nThe list is NULL!\n");
else
{ printf("\nHead");
do { printf("->%d",p->data); p=p->next; } while(p!=NULL);
printf("->End\n");
}
}
void main()
{ SLIST *head;
int a[N]={11,12,15,18,19,22,25,29};
head=creatlist(a);
printf("\nOutput from head:\n"); outlist(head);
printf("\nOutput from tail: \n");
while (head->next != NULL){
fun(head);
printf("\n\n");
printf("\nOutput from head again :\n"); outlist(head);
}
}