创建链表,插入数据,查找数据,删除数据(算法笔记)
#include <iostream>
#include <cstdio>
using namespace std;
const int N=10;
struct node
{
int data;
node* next;
};
node* create(int array[]);
int search(node* head,int x);
void insert(node* head,int pos,int x);
void del(node* head,int x);
int main()
{
int array[N]={1,2,3,4,5,5,6,5,3,9};
node* l=create(array);
node* s=create(array);
node* i=create(array);
node* d=create(array);
l=l->next;
printf("建立链表:\n");
while(l!=NULL)
{
printf("%d ",l->data);
l=l->next;
}
printf("\n查找:\n");
int ans=search(s,5);
printf("%d",ans);
printf("\n插入:\n");
insert(i,3,9);
i=i->next;
while(i!=NULL)
{
printf("%d ",i->data);
i=i->next;
}
printf("\n删除\n");
del(d,3);
d=d->next;
while(d!=NULL)
{
printf("%d ",d->data);
d=d->next;
}
cout << "\nHello world!" << endl;
return 0;
}
node* create(int array[])
{
node *p,*head,*pre;
head=new node;
head->next=NULL;
pre=head;
for(int i=0;i<N;i++)
{
p=new node;
p->data=array[i];
p->next=NULL;
pre->next=p;
pre=p;
}
return head;
}
int search(node* head,int x) //查找单链表中x的个数
{
node *p=head->next;
int count=0;
while(p!=NULL)
{
if(p->data==x)
count++;
p=p->next;
}
return count;
}
void insert(node* head,int pos,int x) //在第pos号插入数据x
{
node* p=head;
for(int i=0;i<pos;i++)
{
p=p->next;
}
node *q=new node;
q->data=x;
q->next=p->next;
p->next=q;
}
void del(node* head,int x) //删除值为x的结点
{
node* p=head->next;
node* q=head;
while(p!=NULL)
{
if(p->data==x)
{
q->next=p->next;
delete(p);
p=q->next;
}
else
{
q=p;
p=p->next;
}
}
}
下面个代码是看c和指针写出来的,但我感觉有点问题!
书上最后一个代码是这样给出的,他想传递的应该是链表第一个结点的地址,而不是头结点的地址,否则头结点是没数据的,即不应该与new_value比较。然而,传递了第一个结点的地址,insert函数必然会移动linkp的位置,因为没有另外的变量存储数据,那么问题来了,在主函数中,输出数据的时候,怎么从第一个数据开始输出,这儿的头结点的位置已经移动到new_value的前面一个节点了。所以,妾以为,用一个变量代替linkp更加合适,此事此时递给linkp的是链表的头结点,即头结点便不用移动,方便后续数据处理或者输出,即我写的那个完整的代码!
//c和指针给的代码
int insert(register node **linkp,int new_value)
{
register node *current;
register node *p;
while((current=*linkp)!=NULL && current->data<new_value)
linkp=¤t->next;
p =(node *)malloc(sizeof(node));
if(p==NULL)
return 0;
p->data=new_value;
p->next=current;
*linkp=p;
return 1;
}
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
struct node
{
int data;
node *next;
};
node *create(int array[],int n);
int insert(register node **linkp,int new_value);
//node* insert(register node **linkp,int new_value);
int main()
{
int a[]={1,4,5,8,9,12,15,2,36,5,9,8,5,5,98};
int n=sizeof(a)/sizeof(a[0]);
sort(a,a+n);
for(int i=0;i<n;i++)
{
printf("%3d",a[i]);
}
printf("\n");
printf("创建链表:\n");
node *q=create(a,n);
q=q->next;
while(q!=NULL)
{
printf("%3d",q->data);
q=q->next;
}
printf("\n");
printf("插入一个数后:\n");
node *i=create(a,n);
insert(&i,-1);
insert(&i,25);
insert(&i,-10);
i=i->next;
while(i!=NULL)
{
printf("%3d",i->data);
i=i->next;
}
printf("\n");
}
node *create(int array[],int n)
{
node *p,*pre,*head;
head=new node;
head->next=NULL;
pre=head;
for(int i=0;i<n;i++)
{
p=new node;
p->data=array[i];
p->next=NULL;
pre->next=p;
pre=p;
}
return head;
}
int insert(register node **linkp,int new_value)
{
register node *precious;
precious=NULL;
register node *current;
register node *p;
current=(*linkp)->next;
while(current!=NULL&¤t->data<new_value)
{
precious=current;
current=current->next;
}
p =(node *)malloc(sizeof(node));
if(p==NULL)
return 0;
p->data=new_value;
p->next=current;
if(precious==NULL)
(*linkp)->next=p;
else
precious->next=p;
free(p);
return 1;
}
经过苦心“修炼”,终于找出了解决办法,insert函数的返回值为 node*,返回头节点:
node* insert(register node **linkp,int new_value)
{
node* pre = *linkp;register node *current;
register node *p;*linkp=(*linkp)->next; //因为是带头结点的链表,所以要取头结点的下一个结点
while((current=*linkp)!=NULL && current->data<new_value)
linkp=¤t->next;
p =(node *)malloc(sizeof(node));
if(p==NULL)
return NULL;
p->data=new_value;
p->next=current;if(pre->next==current) //如果插入的数是在头节点的下一个位置,也就是插入的数最小
pre->next=p;
else
*linkp=p; //不能写成 (*linkp->next)->nect=p ; 原因我尚未弄清楚,我只知道会出现死循环
return pre;
}
整体代码如下:
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
struct node
{
int data;
node *next;
};
node *create(int array[],int n); //带头节点的链表
node* insert(register node **linkp,int new_value);
int main()
{
int a[]={1,4,5,8,9,12,15,2,36,5,9,8,5,5,98};
int n=sizeof(a)/sizeof(a[0]);
sort(a,a+n);
for(int i=0;i<n;i++)
{
printf("%3d",a[i]);
}
printf("\n");
printf("创建链表:\n");
node *q=create(a,n);
q=q->next;
while(q!=NULL)
{
printf("%3d",q->data);
q=q->next;
}
printf("\n");
printf("插入一个数后:\n");
node *i=create(a,n);
i=insert(&i,-1);
i=insert(&i,25);
i=insert(&i,-10);
i=i->next;
while(i!=NULL)
{
printf("%3d",i->data);
i=i->next;
}
}
node *create(int array[],int n)
{
node *p,*pre,*head;
head=new node;
head->next=NULL;
pre=head;
for(int i=0;i<n;i++)
{
p=new node;
p->data=array[i];
p->next=NULL;
pre->next=p;
pre=p;
}
return head;
}
node* insert(register node **linkp,int new_value) //返回头节点
{
node* pre = *linkp;
register node *current;
register node *p;
*linkp=(*linkp)->next; //因为是带头结点的链表,所以要取头结点的下一个结点
while((current=*linkp)!=NULL && current->data<new_value)
linkp=¤t->next;
p =(node *)malloc(sizeof(node));
if(p==NULL)
return NULL;
p->data=new_value;
p->next=current;
if(pre->next==current) //如果插入的数是在头节点的下一个位置,也就是插入的数最小
pre->next=p;
else
*linkp=p; //不能写成 (*linkp->next)->nect=p ; 原因我尚未弄清楚,我只知道会出现死循环
return pre;
}