线性表的链接存储
链接存储中,每个存储结点不仅含有所存元素本身的信息,而且含有元素之间的逻辑关系信息,
其中data表示值域,用来存储一个元素,p1,p2,…pm(m>1)均为指针域,每个指针的值为其对应后继元素或前驱元素所在结点的存储位置。
单链表中的结点类型 :
struct sNode{
ElemType data ;
struct sNode* next ;
}
双向链表中的结点类型:
struct dNode{
ElemType data;
struct dNode* left;
struct dNode* right;
}
线性表操作在单链表上的实现
1.初始化线性表,即置单链表的表头为空
void InitList(struct sNode** HL){
*HL = NULL;
}
初始化一个单链表就是把表头指针变量置为空,为此必须把该表头指针变量的地址作为实际参数,传送给初始化算法的形式参数,通过在算法中把该形式参数的值所指向的对象置为空。由于传送给该初始化算法的实际参数是一个单链表的表头指针变量的地址,所以该算法的形式参数HL的类型应定义为单链表结点类型的二级指针类型。
2.清除线性表L中的所有元素,即释放单链表中的所有结点,使之成为一个空表
void clearList(struct sNode** HL){
//用cp和np分别作为指向两个相邻结点的指针
struct sNode *cp,*np;
//单链表表头指针赋给cp
cp = *HL;
while(cp != NULL){
np = cp->next;//保存下一个结点的指针
free(cp); //回收由cp所指向的当前结点
cp = ne; //使下一个几点成为当前结点
}
//置单链表的表头指针为空
*HL = NULL;
}
3.返回线性表L的长度,即单链表的长度
int SizeList(struct sNode* HL){
int i = 0;
while(HL != NULL){
i++; //统计结点个数
HL = HL->next; //遍历单链表,统计结点个数
}
return i;
}
4.减产单链表是否为空,若为空则返回1,否则返回0
int EmptyList(struct sNode* HL){
if(HL == NULL)
return 1;
else
return 0;
}
5.返回单链表中第pos个结点中的元素,若pos超出范围,则停止程序运行
/*
1.检查pos值是否小于1,若是则中止程序运行
2.从表头起依次统计扫描到的每一个结点,若扫描到第pos个结点则退出统计
3.返回扫描到的第pos个结点的值,或者当不存在第pos个结点时,则退出运行
*/
ElemType GetElem(struct sNode* HL , int pos){
int i=0;
if(pos<1){
printf("pos值非法,退出运行");
exit(1);
}
while(HL != NULL){
i++;
if(i == pos) break;
HL = HL->next;
}
if(HL != NULL)
return HL->data;
else{
printf("pos值非法,退出运行");
exit(1);
}
}
6.遍历一个单链表
void TraverseList(struct sNode* HL){
while(HL != NULL){
printf("%d",Hl->data);
HL = HL->next;
}
printf("\n");
}
7.从单链表中查找具有给定值x的第一个元素,若查找成功则返回给结点data域的存储地址,否则返回NULL
ElemType* FindList(struct sNode* HL ,ElenType x){
while(HL != NULL){
if(HL->data == x)
return &HL->data;
else
HL = HL->next;
}
return NULL;
}
8.把单链表中第pos个结点的值修改为x的值,若修改成功返回1,否则返回0
int UpdatePosList(struct sNode* HL ,int pos, ElemType x){
int i = 0;
struct sNode* p = HL;
while(p!=NULL){
i++;
if(pos == i)
break;
else
p=p->next;
}
if(pos == i){
p->data = x;
return 1;
}
else{
return 0;
}
}
9.向单链表的表头出啊如一个元素
void InsertFirstList(struct sNode** HL,ElemType x){
//若分配失败,则停止插入,退出程序
struct sNOde *newp;
newp = (sNode*)malloc(sizeof (struct sNode));
if(newp == NULL){
printf("内存动态空间用完,退出运行");
exit(1);
}
//赋值
newp->data = x;
//把新的结点作为头结点
newp->next = *HL;
*HL=newp;
}
10.向单链表的末尾添加一个元素
void InsertLastList(struct sNode* HL,ElemType x){
struct sNode *newp;
newp = (sNode*)malloc(sizeof(struct sNode));
if(newp == NULL){
printf("内存动态空间用完,退出运行");
exit(1);
}
//赋值
newp->data = x;
newp->next = NULL;
if(*HL == NULL){
//若原表为空则作为头结点插入
*HL = newp;
}
else{
//查找到表尾并插入结点
struct sNode* p = *HL;
while(p->next != NULL)
p = p->next;
p->next = newp;
}
}
11.向单链表中第pos个基点位置插入元素为x的结点,若插入成功返回1,否则返回0
int InsertPosList(struct sNode** HL,int pos ,ElemType x){
int i = 0;
struct sNOde *newp;
struct sNode* cp = *HL,*ap = NULL;
//处理pos小于0的情况
if(pos<=0){
printf("pos值不正确,插入失败");
return 0 ;
}
//查找第pos个结点
while(cp != NULL){
i++;
if(pos == i)
break;
else{
ap = cp;
cp = cp->next;
}
}
//产生新结点
newp = (sNode*)malloc(sizeof(struct sNode));
if(newp == NULL){
printf("内存动态空间用完,无法插入");
return 0;
}
//把x赋值给新的结点的data域
newp->data = x;
if(ap == NULL){
//把新节点插入到表头
newp->next = cp;
*HL = newp;
else{
//把新结点插入到ap和cp之间
newp-next = cp;
ap->next = newp;
}
return 1;
}
12.向有序单链表中擦汗如元素x结点,使得插入后仍有序
/*
1.为新元素动态分配结点并赋值
2.若单链表为空或新元素小于头结点元素,则插入到表头
3.查找插入位置
4.完成插入操作
*/
void InsertOrderList(struct sNode** HL,ElemType x){
struct Snode* cp = *HL,*ap=NULL;
//建立新结点
struct sNode *newp;
newp = malloc(sizeof(struct sNode));
if(newp == NULL){
printf("内存动态空间用完,退出运行");
exit(1);
}
newp->data = x;
//插入到表头
if(cp ==NULL || x < cp->data){
newp->next = cp;
*HL = newp;
return;
}
//查找插入如位置
while(cp != NULL){
if(x < cp->data)
break;
else{
ap = cp;
cp = cp->next;
}
}
//把x结点插入到ap和cp之间
newp->next = cp;
ap->next = newp;
}
13.从单链表中删除表头结点,并把该结点值返回,若删除失败则停止程序
ElemType DeleteFirstList(struct sNode** HL){
ElemType temp;
struct sNode* p = *HL;
if(*HL == NULL){
printf("单链表为空,退出运行");
exit(1);
}
//使表头指针指向第二个结点
*HL = (*HL)->next;
temp = p->data;
free(p);
return temp;
}
14.从单链表中删除表尾结点并返回它的值,若删除失败则停止程序运行
ElemType DeleteLastList(struct sNode** HL){
ElemType temp;
struct sNode* cp = *HL;
struct sNOde* ap = NULL;
//单链表为空则停止运行
if(cp == NULL){
printf("单链表为空,退出运行");
exit(1);
}
//查找尾结点
while(cp->next != NULL){
ap = cp;
cp = cp->next;
}
//若单链表中只有一个结点,则需要修改表头指针
if(ap == NULL){
*HL=(*HL)->next;
}else{
ap->next = NULL;
}
temp = cp->data;
free(cp);
return temp;
}
15.从单链表中删除第pos个结点并返回它的值,若删除失败则停止程序运行
ElemType DeletePosList(struct sNode** HL,int pos){
int i = 0;
ElemType temp;
struct sNode* cp = *HL;
struct sNOde* ap = NULL;
//单链表为空或pos值不正确
if(cp==NULL || pos <= 0){
printf("单链表为空或pos值不正确");
exit(1);
}
//查找第pos个结点
while(cp != NULL){
i++;
if(i == pos) break;
ap = cp;
cp = cp->next;
}
//没有第ois个结点
if(cp == NULL){
printf("pos值不正确");
exit(1)
}
//若pos等于1,删除头结点
if(pos == 1){
*HL = (*HL)->next;
}else{
ap->next = cp->next;
}
temp = cp->data;
free(cp);
return temp;
}
16.从单链表中删除值为x的第一个结点,若删除成功返回1否则返回0
int DeleteValueList (struct sNode** HL,ElemType x){
struct sNode* cp = *HL;
struct sNode* ap = NULL;
//查找值为x的结点
while(cp != NULL){
if(cp->data == x) break;
ap = cp;cp = cp->next;
}
//若查找失败,即单链表中不存在值为x的结点,则返回0
if(cp = NULL) return 0;
//对删除的表头或非表头进行处理
if(ap == NUll){
*HL = (*HL)->next
}else{
ap->next = cp->next;
}
free(cp);
return 1;
}