一、Xmind整理:
链表的插入和删除:
二、课上练习:
练习1:顺序表去重
33 22 22 11 11 i jfor(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剩余元素存到lcwhile(p<la->len){lc->data[lc->len++]=la->data[p++];}//吧lb剩余元素存到lcwhile(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;}//3.找到pos-1位置起名pLinklist p=L;for(int i=0;i<pos-1;i++){p=p->next;}//4.删除p->nextLinklist q=p->next;p->next=q->next;free(q);q=NULL;return L;
}
3.单链表任意位置查找
/** function: 按链表位置查找* @param [ in] * @param [out] * @return */
int search_by_data(datatype key,Linklist L)
{//1.判空int len=Len_linklist(L);if(NULL==L||key<1||key>(len=Len_linklist(L))+1){puts("search error\n");return -1;}Linklist p=L;for(int i=1;i<key;i++){p=p->next;}printf("%d\n",p->data);
}
4.单链表任意位置修改
/** function: 按链表位置修改* @param [ in] * @param [out] * @return */
Linklist update_by_pos(datatype key,datatype e,Linklist L)
{int len=Len_linklist(L);if(NULL==L||key<1||key>(len=Len_linklist(L))+1){puts("search error\n");return L;}Linklist p=L;for(int i=1;i<key;i++)p=p->next;p->data=e;return L;
}
整体代码如下:
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_data(int key,Linklist L);
Linklist update_by_pos(datatype key,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;}//3.找到pos-1位置起名pLinklist p=L;for(int i=0;i<pos-1;i++){p=p->next;}//4.删除p->nextLinklist q=p->next;p->next=q->next;free(q);q=NULL;return L;
}
/** function: 按链表位置查找* @param [ in] * @param [out] * @return */
int search_by_data(datatype key,Linklist L)
{//1.判空int len=Len_linklist(L);if(NULL==L||key<1||key>(len=Len_linklist(L))+1){puts("search error\n");return -1;}Linklist p=L;for(int i=1;i<key;i++){p=p->next;}printf("%d\n",p->data);
}
/** function: 按链表位置修改* @param [ in] * @param [out] * @return */
Linklist update_by_pos(datatype key,datatype e,Linklist L)
{int len=Len_linklist(L);if(NULL==L||key<1||key>(len=Len_linklist(L))+1){puts("search error\n");return L;}Linklist p=L;for(int i=1;i<key;i++)p=p->next;p->data=e;return L;
}
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);//按链表位置查找datatype key;printf("please enter search key:");scanf("%d",&key);search_by_data(key,L);//按链表位置修改printf("please enter update pos:");scanf("%d",&key);printf("please enter update element:");scanf("%d",&e);update_by_pos(key,e,L);output(L);return 0;
}