一、Xmind整理:
链表的插入和删除:
二、课上练习:
练习1:顺序表去重
33 22 22 11 11
i
j
for(int i=0;i<list->len-1;i++)
{
for(int j=i+1;j<len;j++)
{
if(list->data[i]==list->data[j])
{
delete_by_sub(j,list);
j--; //防止漏删
}
}
}
练习2: 顺序表合并
/*
* function: 顺序表有序合并
* @param [ in]
* @param [out]
* @return 无
*/
void combine(Seqlist *la,Seqlist *lb,Seqlist *lc)
{
int p=0;//la的下表
int q=0;//lb的下表
while(p<la->len && q<lb->len)
{
if(la->data[p] <=lb->data[q])
{
lc->data[lc->len++]=la->data[p++];
}
else
{
lc->data[lc->len++]=lb->data[q++];
}
}
//吧la剩余元素存到lc
while(p<la->len)
{
lc->data[lc->len++]=la->data[p++];
}
//吧lb剩余元素存到lc
while(q<lb->len)
{
lc->data[lc->len++]=lb->data[q++];
}
}
练习3: 单链表创建
/*
* function: 创建一个节点
* @param [ in]
* @param [out]
* @return
*/
Linklist create_node()
{
Linklist node=(Linklist)malloc(sizeof(struct Node));
if(NULL==node)
return NULL;
node->data=0;
node->next=NULL;
return node;//0x10
}
练习4:单链表头插
/*
* function: 头插
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
Linklist insert_head(datatype e,Linklist L)
{
//在堆区创建一个节点
Linklist node=create_node();
node->data=e;
node->next=L;
L=node;
return L;
}
练习5:单链表尾插
/*
* function: 尾插
* @param [ in]
* @param [out]
* @return
*/
Linklist insert_rear(datatype e,Linklist L)
{
//创建一个新节点
Linklist s=create_node();
s->data=e;
if(L==NULL)
{
L=s;
}
else
{
//rear指向最后一个节点的地址
Linklist rear=L;
while(rear->next!=NULL)
{
rear=rear->next;
}
rear->next=s;
}
return L;
}
练习6: 单链表头删
/*
* function: 头删除
* @param [ in]
* @param [out]
* @return
*/
Linklist delete_head(Linklist L)
{
//判断链表是否为空
if(NULL==L)
{
return L;
}
if(L->next==NULL)
{
free(L);
L=NULL;
}
else
{
Linklist q=L->next;
L->data=q->data;
L->next=q->next;
free(q);
q=NULL;
}
return L;
}
练习7: 单链表尾删
/*
* function: 尾部删除
* @param [ in]
* @param [out]
* @return
*/
Linklist delete_rear(Linklist L)
{
//1,判断链表是否为空
if(NULL==L)
{
return NULL;
}
//2,判断如果链表只有一个节点
else if(L->next==NULL)
{
free(L);
L=NULL;
}
else
{
//3,有多个节点
//循环倒数第二个节点
Linklist second=L;
while(second->next->next!=NULL)
{
second=second->next;
}
free(second->next);
second->next=NULL;
}
return L;
}
练习8:单链表遍历
/*
* function: 循环遍历
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
int output(Linklist L)
{
//判断是否创建
//判断是否为空
if(NULL==L )
{
return -1;
}
while(L!=NULL)
{
printf("%d\t",L->data);
L=L->next;
}
puts("");
}
练习9:单链表任意位置插入
int Len_linklist(Linklist L)
{
int count=0;
while(L!=NULL)
{
count++;
L=L->next;
}
return count;
}
/*
* function: 按位置插入
* @param [ in]
* @param [out]
* @return
*/
Linklist insert_by_pos(int pos,datatype e,Linklist L)
{
//1,判断链表是否为空
//2,判断位置是否合法
int len;
if(NULL==L || pos<1 || pos>(len=Len_linklist(L))+1)
{
puts("insert arror");
return L;
}
//3,插入
Linklist p=L;
if(pos==len+1)
{
insert_rear(e,L);
return L;
}
for(int i=1;i<pos;i++)
{
p=p->next;
}
//在p节点后面插入新节点s
Linklist s=create_node();
s->next=p->next;
p->next=s;
s->data=p->data;
p->data=e;
return L;
}
三、课后作业:
1.顺序表排序
test.c核心代码:
/*
* function: 排序
* @param [ in]
* @param [out]
* @return
*/
int SeqlistSort(Seqlist *list)
{
int i,j,count;
datatype t;
if(NULL==list||empty(list))
return -1;
for(i=1;i<list->len;i++)
{
count=0;
for(j=0;j<list->len-i;j++)
{
if(list->data[j]>list->data[j+1])
{
t=list->data[j];list->data[j]=list->data[j+1];list->data[j+1]=t;
count++;
}
}
if(count==0)
break;
}
return 0;
}
2.单链表任意位置删除
/*
* function: 按链表位置删除
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
Linklist delete_by_pos(int pos,Linklist L)
{
//1,判断链表是否为空
//2.判断位置是是否合法
int len;
if(NULL==L||pos<1||pos>(len=Len_linklist(L))+1)
{
puts("delete error\n");
return L;
}
if(pos==1)
{
delete_head(L);
}
else
{
//3.找到pos-1位置起名p
Linklist p=L;
for(int i=1;i<pos-1;i++)
{
p=p->next;
}
//4.删除p->next
Linklist q=p->next;
p->next=q->next;
free(q);
q=NULL;
}
return L;
}
3.单链表任意位置查找
/*
* function: 按链表位置查找
* @param [ in]
* @param [out]
* @return
*/
int search_by_pos(int pos,Linklist L)
{
//1.判空
int len=Len_linklist(L);
if(NULL==L||pos<1||pos>(len=Len_linklist(L))+1)
{
puts("search error\n");
return -1;
}
Linklist p=L;
for(int i=1;i<pos;i++)
{
p=p->next;
}
printf("%d\n",p->data);
}
4.单链表任意位置修改
/*
* function: 按链表位置修改
* @param [ in]
* @param [out]
* @return
*/
int update_by_pos(int pos,datatype e,Linklist L)
{
int len=Len_linklist(L);
if(NULL==L||pos<1||pos>(len=Len_linklist(L))+1)
{
puts("update error\n");
return -1;
}
Linklist p=L;
for(int i=1;i<pos;i++)
p=p->next;
p->data=e;
return 0;
}
整体代码如下:
head.h:
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int datatype;
//定义单链表节点结构体
typedef struct Node
{
//数据域:数据元素
datatype data;
//指针域:存储下一个节点的地址
struct Node *next;
}*Linklist;
Linklist create_node();
Linklist insert_head(datatype e,Linklist L);
int output(Linklist L);
Linklist insert_rear(datatype e,Linklist L);
Linklist delete_head(Linklist L);
Linklist delete_rear(Linklist L);
int Len_linklist(Linklist L);
Linklist insert_by_pos(int pos,datatype e,Linklist L);
Linklist delete_by_pos(int pos,Linklist L);
int search_by_pos(int pos,Linklist L);
int update_by_pos(int pos,datatype e,Linklist L);
#endif
test.c:
#include "head.h"
/*
* function: 创建一个节点
* @param [ in]
* @param [out]
* @return
*/
Linklist create_node()
{
Linklist node=(Linklist)malloc(sizeof(struct Node));
if(NULL==node)
return NULL;
node->data=0;
node->next=NULL;
return node;
}
/*
* function: 头插
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
Linklist insert_head(datatype e,Linklist L)
{
//在堆区创建一个节点
Linklist node=create_node();//在堆区申请一个节点
node->data=e;//数据域赋值为e
//node节点链接到链表中
node->next=L;
L=node;
return L;//因为自定义函数指针的改变不影响实参,需要返回
}
/*
* function: 循环遍历
* @param [ in]
* @param [out]
* @return
*/
int output(Linklist L)
{
//判断是否创建
//判断是否为空
if(NULL==L)
{
return -1;
}
while(L!=NULL)
{
printf("%d\t",L->data);
L=L->next;
}
printf("\n");
}
/*
* function: 尾部插入
* @param [ in]
* @param [out]
* @return
*/
Linklist insert_rear(datatype e,Linklist L)
{
Linklist s=create_node();
s->data=e;
if(L==NULL)
{
L=s;
}
else
{
Linklist rear=L;
while(rear->next!=NULL)
{
rear=rear->next;
}
rear->next=s;
}
return L;
}
/*
* function: 头删除
* @param [ in]
* @param [out]
* @return
*/
Linklist delete_head(Linklist L)
{
//判断链表是否为空
if(NULL==L)
{
return L;
}
if(L->next==NULL)
{
free(L);
L=NULL;
}
else
{
Linklist q=L->next;
L->data=q->data;
L->next=q->next;
free(q);
q=NULL;
}
return L;
}
/*
* function: 尾部删除
* @param [ in]
* @param [out]
* @return
*/
Linklist delete_rear(Linklist L)
{
//1.判断链表是否为空
if(NULL==L)
{
return NULL;
}
//2.判断如果链表只有一个节点
else if(L->next==NULL)
{
free(L);
L=NULL;
}
else
{
//3.有多个节点
//循环倒数第二个节点
Linklist second=L;
while(second->next->next!=NULL)
{
second=second->next;
}
free(second->next);
second->next=NULL;
}
return L;
}
/*
* function: 计算长度
* @param [ in]
* @param [out]
* @return
*/
int Len_linklist(Linklist L)
{
int count=0;
while(L!=NULL)
{
count++;
L=L->next;
}
return count;
}
/*
* function: 按链表位置插入
* @param [ in]
* @param [out]
* @return
*/
Linklist insert_by_pos(int pos,datatype e,Linklist L)
{
//1.判断链表是否为空
//2.判断位置是否合法
int len;
if(NULL==L||pos<1||pos>(len=Len_linklist(L))+1)
{
puts("insert error\n");
return L;
}
//3.插入
Linklist p=L;
if(pos==len+1)
{
insert_rear(e,L);
return L;
}
for(int i=1;i<pos;i++)
{
p=p->next;
}
//在p节点后面插入新节点s
Linklist s=create_node();
s->next=p->next;
p->next=s;
s->data=p->data;
p->data=e;
return L;
}
/*
* function: 按链表位置删除
* @param [ in]
* @param [out]
* @return 成功返回0 失败返回-1
*/
Linklist delete_by_pos(int pos,Linklist L)
{
//1,判断链表是否为空
//2.判断位置是是否合法
int len;
if(NULL==L||pos<1||pos>(len=Len_linklist(L))+1)
{
puts("delete error\n");
return L;
}
if(pos==1)
{
delete_head(L);
}
else
{
//3.找到pos-1位置起名p
Linklist p=L;
for(int i=1;i<pos-1;i++)
{
p=p->next;
}
//4.删除p->next
Linklist q=p->next;
p->next=q->next;
free(q);
q=NULL;
}
return L;
}
/*
* function: 按链表位置查找
* @param [ in]
* @param [out]
* @return
*/
int search_by_pos(int pos,Linklist L)
{
//1.判空
int len=Len_linklist(L);
if(NULL==L||pos<1||pos>(len=Len_linklist(L))+1)
{
puts("search error\n");
return -1;
}
Linklist p=L;
for(int i=1;i<pos;i++)
{
p=p->next;
}
printf("%d\n",p->data);
}
/*
* function: 按链表位置修改
* @param [ in]
* @param [out]
* @return
*/
int update_by_pos(int pos,datatype e,Linklist L)
{
int len=Len_linklist(L);
if(NULL==L||pos<1||pos>(len=Len_linklist(L))+1)
{
puts("update error\n");
return -1;
}
Linklist p=L;
for(int i=1;i<pos;i++)
p=p->next;
p->data=e;
return 0;
}
main.c:
#include "head.h"
int main(int argc, const char *argv[])
{
Linklist L=NULL;
int n;
datatype e;
printf("please enter n:");
scanf("%d",&n);
/*
for(int i=0;i<n;i++)
{
printf("please enter element:");
scanf("%d",&e);
//头插:在头指针当前节点插入
L=insert_head(e,L);
}
*/
//在主函数找到尾部节点
Linklist rear=L;
if(rear!=NULL)
{
while(rear->next!=NULL)
{
rear=rear->next;
}
}
//尾部插入
for(int i=0;i<n;i++)
{
printf("please enter element:");
scanf("%d",&e);
L=insert_rear(e,L);
}
//循环链表
output(L);
//头删
//L=delete_head(L);
//output(L);
//尾删
//L=delete_rear(L);
//output(L);
//按链表位置插入
int pos;
printf("please enter insert pos:");
scanf("%d",&pos);
printf("please enter insert element:");
scanf("%d",&e);
L=insert_by_pos(pos,e,L);
output(L);
//按链表位置删除
printf("please enter delete pos:");
scanf("%d",&pos);
L=delete_by_pos(pos,L);
output(L);
//按链表位置查找
printf("please enter search pos:");
scanf("%d",&pos);
search_by_pos(pos,L);
//按链表位置修改
printf("please enter update pos:");
scanf("%d",&pos);
printf("please enter update element:");
scanf("%d",&e);
update_by_pos(pos,e,L);
output(L);
return 0;
}