【数据结构】:
typedef int ElemType;
typedef struct Node{
ElemType data;
struct Node *next;头
}Node,*LinkList; //初始化单链表
【算法思想】:
(1)初始化:我们先初始化建立一张空的单链表。
(2)添加结点:本次实验我使用了尾插法,该方法是将新结点插到当前单链表的表尾上。为此需增加一个尾指针r,使之指向当前单链表的表尾。
(3)按序号查找:在单链表中,由于每个结点的存储位置都放在其前一结点的next域中,所以即使知道被访问结点的序号i,也不能像顺序表那样直接按序号i访问一维数组中的相应元素,只能从链表的头指针出发,顺链域next逐个结点往下搜索,直至搜索到第i个结点为止。
(4)查找单链表中的数据:采用指针P依次指向各个结点,并附设计数器j计数,判断输出链表数据。
(5)插入操作:找到单链表中第i-1个结点并由指针pre指示,再申请一个新结点,将其数据域的值置为e。
(6)通过修改指针域将新结点s挂入单链表L。
(7)删除操作:通过计数方式找到第i-1个结点并由指针pre指示,删除第i个结点并释放结点空间。
(8)合并有序表:首先我们要输入两张表,要求利用现有的表LA和LB中结点空间来建立新表LC,可通过更改结点的next域来重建新的元素之间的线性关系。为保证新表仍然递增有序,可以利用尾插入法建立单链表。
【算法描述】:
(1)初始化表
LinkList InitList(LinkList L){
L=(LinkList)malloc(sizeof(Node));//这是动态分配,分配的空间大小,建立头结点。
// if(!L->next) //把指针看成整型,指针为NULL相当于指针等于零。所以L.elem==NULL则!L.elem为真。 判断空间分配是否成功
// return ERROR; //创建失败则返回0;
(L)->next=NULL; //建立空的单链表L
return L;
}
(2) 尾插法添加结点
int CreateFromTail(LinkList L){
char c;
Node *r,*s;
int flag = 1;
r=L;
while(flag){
scanf("%d",&c);
if(c!=-100){
s=(Node*)malloc(sizeof(Node));
s->data=c;
r->next=s;
r=s;
}else{
flag=0;
r->next=NULL;
}
}
return OK;
}
(3)查找的函数(按序号查找)
int Get(LinkList L,int i){
int j;
Node *p;
if(i<=0)return ERROR;
p=L;j=0; //从头开始扫描
while((p->next!=NULL)&&(j<i))
{
p=p->next;
j++;
}
if(i==j) {
printf("你查找的第%d位的结点,数值是%d\t",i,p->data);
return OK;
}
else return ERROR;
}
(4)据长度输出单链表的数据
int Cha(LinkList L){
Node * p;
p=L->next;
int j=0;
while(p!=NULL){
printf("%d\t",p->data);
p=p->next;
j++;
}
return OK;
}
(5)插入操作
int InsList(LinkList L,int i,ElemType e){
//在带头结点的单链表L中第i个位置插入值为e的新结点。
Node *pre,*s;
int k;
if(i<=0) return ERROR;
pre=L;k=0; //从头开始查找第i-1个结点。
while(pre!=NULL&&k<i-1){ //一直循环,直到找到pre指向第i-1个
pre=pre->next;
k=k+1;
}
if(pre==NULL){
printf("插入位置不合理。");
return ERROR;
}
s=(Node*)malloc(sizeof(Node));
s->data=e;
s->next=pre->next;
pre->next=s;
return OK;
}
(6) /单链表的删除操作
int DelList(LinkList L,int i,ElemType e){
Node *pre,*r;
int k;
pre=L;k=0;
while(pre->next!=NULL&&k<i-1){ // 2
pre=pre->next;
k=k+1;
}
if(pre->next==NULL){
printf("删除结点的位置不合法!");
return ERROR;
}
r=pre->next;
pre->next=r->next; //修改指针,删除结点。
e=r->data;
free(r); //释放结点
return OK;
}
(7)合并两个有序表
LinkList MergeLinkList(LinkList LA,LinkList LB){
Node *pa,*pb,*r;
LinkList LC;
pa=LA->next;
pb=LB->next;
LC=LA;
LC->next=NULL;
r=LC;
while(pa!=NULL&&pb!=NULL){
if(pa->data<=pb->data){
r->next=pa;r=pa;pa=pa->next;
}else{
r->next=pb;r=pb;pb=pb->next;
}
}
if(pa)
r->next=pa;
else
r->next=pb;
free(LB);
return(LC);
}
(8)最后就是在main函数中调用了。
int main(){
int i,x,y;
LinkList LA,LB,LC;
Node *L;
ElemType e;
LA=InitList(LA);
// if(i==1)printf("成功!");
printf("输入你要添加的结点,以-100结束:\n");
i=CreateFromTail(LA);
if(i==1)Cha(LA);
printf("\n你输入你要查找的序号:\n");
scanf("%d",&i);
i=Get(LA,i);
if(i==1)printf("查找成功!\n");
else printf("结点序号不正确\n");
printf("请输入要插入的结点位置:\n");
scanf("%d",&x);
printf("\n请输入要插入的结点数据:\n");
scanf("%d",&y);
i=InsList(LA,x,y);
if(i==1)Cha(LA);
printf("\n请输入要删除的结点位置:\n");
scanf("%d",&x);
i =DelList(LA,x,e);
if(i==1)Cha(LA);
printf("\n请输入第二张单链表结点,以-100结束:\n");
LB=InitList(LB); //初始化
i=CreateFromTail(LB);
if(i==1)Cha(LB);
printf("\n接下来就是合并了:\n");
LC=MergeLinkList(LA,LB);
if(LC!=NULL)Cha(LC);
}
(9)最后运行的示意图:
源码下载:
https://download.csdn.net/download/weixin_42868605/21006682