数据结构--线性表--链式存储
跟线性存储一样,我添加了17,18两个函数.不过感觉17不够好,用到了goto.
编译器:gcc
#include <stdio.h> typedef int elemType; struct sNode{ elemType data; struct sNode *next; }; /* 1.初始化线性表,即置线性表的头指针为空 */ void initList(struct sNode **hp) { *hp = NULL; return; } /* 2.清楚线性表L中所有元素,即释放单链表L中所有节点,使之成为一个空表 */ void clearList(struct sNode **hp) { if(*hp == NULL) return; struct sNode *temp,*next; temp=*hp; while(temp != NULL) { next = temp->next; free(temp); temp = next; } *hp = NULL; return; } /* 3.返回单链表的长度*/ int sizeList(struct sNode *hp) { int size=0; while(hp!=NULL) { size+=1; hp=hp->next; } return size; } /* 4.检查单链表是否为空,空返回1,否则返回0*/ int emptyList(struct sNode *hp) { if(hp == NULL) return 1; else return 0; } /* 5.返回单链表中第pos个节点的元素值,若pos超出范围,则停止程序运行*/ elemType getElem(struct sNode *hp, int pos) { int size = sizeList(hp); if(pos<1 && pos>size) { printf("pos位置越界.\n"); exit(1); } int i = 1; while(i!=pos) { i+=1; hp=hp->next; } return hp->data; } /* 6.遍历一个单链表*/ void travelList(struct sNode *hp) { while(hp != NULL) { printf("%d ",hp->data); hp = hp->next; } } /* 7.从单链表中查找值为x的第一个元素,若查找成功返回该节点data域的存储地址,否则返回NULL*/ elemType *findList(struct sNode *hp, elemType x) { if(hp == NULL) { printf("链表为空,无法查找%d\n",x); return NULL; } while(hp != NULL) { if(hp->data == x) return &hp->data; hp = hp->next; } return NULL; } /* 8.把单链表中第pos个节点的值修改为x,若修改成功返回1,否则返回0*/ int updataPosList(struct sNode *hp, int pos, elemType x) { int size = sizeList(hp); if(pos<1 && pos>size) { printf("pos位置越界.\n"); return 0; } int i = 1; while(i!=pos) { i+=1; hp=hp->next; } hp->data = x; return 1; } /* 9.向单链表的表头插入一个元素x */ void insertFirstList(struct sNode **hp, elemType x) { struct sNode *newN; newN = malloc(sizeof(struct sNode)); if(newN == NULL) { printf("创建新节点失败\n"); exit(1); } newN->data = x; newN->next = *hp; *hp = newN; return; } /* 10.向单链表的末尾添加一个元素x */ void insertLastList(struct sNode **hp, elemType x) { struct sNode *newN; newN = malloc(sizeof(struct sNode)); if(newN == NULL) { printf("创建新节点失败\n"); exit(1); } newN->data = x; newN->next = NULL; struct sNode *temp = *hp; if(temp == NULL) { *hp = newN; return; } while(temp->next != NULL) { temp = temp->next; } temp->next = newN; return; } /* 11.向单链表中第pos个节点位置插入元素x,成功返回1,否则返回0 */ int insertPosList(struct sNode **hp, int pos, elemType x) { /*判断pos位置*/ int size = sizeList(*hp); if(pos<1 && pos>size) { printf("pos位置越界.\n"); return 0; } if(pos==1 && pos==size) { printf("请使用头插或尾插方法.\n"); return 0; } /*创建新节点*/ struct sNode *newN; newN = malloc(sizeof(struct sNode)); if(newN == NULL) { printf("创建新节点失败\n"); exit(1); } newN->data = x; /*定位到pos位置的前一个节点*/ int i = 1; struct sNode *temp = *hp; while(i!=pos-1) { i+=1; temp=temp->next; } /*插入*/ newN->next = temp->next; temp->next = newN; return 1; } /* 12.向有序单链表中插入元素x,使得插入后仍然有序 */ void insertOrderList(struct sNode **hp, elemType x) { /*若单链表为空*/ if(*hp==NULL) { insertFirstList(hp,x); return; } struct sNode *temp = *hp; while(1) { if(temp->next == NULL) { if(temp->data < x) { insertLastList(hp,x); return; }else{ insertFirstList(hp,x); return; } } if(temp->next->data > x) { break; }else{ temp = temp->next; } } /*创建新节点*/ struct sNode *newN; newN = malloc(sizeof(struct sNode)); if(newN == NULL) { printf("创建新节点失败\n"); exit(1); } newN->data = x; /*执行插入*/ newN->next=temp->next; temp->next=newN; return; } /* 13.从单链表中删除表头节点,并把该节点的值返回,若删除失败则停止运行 */ elemType deleteFirstList(struct sNode **hp) { if(*hp == NULL) exit(1); struct sNode *temp = *hp; elemType data; *hp = temp->next; data = temp->data; free(temp); return data; } /* 14.从单链表中删除表尾节点并返回它的值,若删除失败则停止运行 */ elemType deleteLastList(struct sNode **hp) { if(*hp == NULL) exit(1); struct sNode *temp = *hp; struct sNode *next = *hp; elemType data; while(next->next != NULL) { temp = next; next = next->next; } data = next->data;
if(next == *hp)
{
*hp = NULL;
}else{
temp->next = NULL;
}
free(next);
return data; } /* 15.从单链表中删除第pos个节点,返回其值,若删除失败则停止运行 */ elemType deletePosList(struct sNode **hp, int pos) { if(*hp == NULL) exit(1); /*判断pos位置*/ int size = sizeList(*hp); if(pos<1 && pos>size) { printf("pos位置越界.\n"); exit(1); } if(pos==1 && pos==size) { printf("请使用头删或尾删方法.\n"); exit(1); } struct sNode *temp = *hp; struct sNode *next; elemType data; int i = 1; while(i != pos-1) { i += 1; temp = temp->next; } next = temp->next; data = next->data; temp->next = next->next; free(next); return data; } /* 16.从单链表中删除值为x的第一个节点,若删除成功则返回1,否则返回0 */ int deleteValudeList(struct sNode **hp, elemType x) { if(*hp == NULL) { printf("单链表空\n"); return 0; } struct sNode *temp = *hp; struct sNode *next = *hp; while(next != NULL) { if(next->data == x) { break; }else{ temp = next; next = next->next; } } if(next == NULL) { printf("链表中无值为x的节点.\n"); return 0; }else{ temp->next = next->next; free(next); return 1; } } /* 17.删除单链表中所有为x的节点 */ void deleteSameList(struct sNode **hp, elemType x) { if(*hp == NULL) { printf("单链表空\n"); return; } struct sNode *temp = *hp; struct sNode *next = *hp; again: /*若刚好为第一个节点,由于此时temp,next指针位置相同,并不常规化,所以特殊处理.*/ if(temp->data == x) { next = temp->next; *hp = temp->next; free(temp); temp = *hp; goto again; } /*当前节点不为空*/ while(next != NULL) { /*当前节点data = x,跳出*/ if(next->data == x) { break; }else{ /*保存当前节点位置,next指向下一个节点*/ temp = next; next = next->next; } } /*若果next指向链表尾null,表示无与x相同节点*/ if(next == NULL) { return; }else{/*有与x相同节点*/ temp->next = next->next; free(next); next = temp->next; goto again; } } /* 18.去除单链表中重复的元素,保留第一个 */ void deleteRepeatList(struct sNode **hp) { struct sNode *temp = *hp; elemType data; while(temp != NULL) { data = temp->data; temp=temp->next; deleteSameList(&temp,data); } } /***************************************************/ int main(void) { struct sNode *hp; #if 1 initList(&hp); insertLastList(&hp,1); insertFirstList(&hp,2); insertLastList(&hp,3); insertLastList(&hp,2); insertLastList(&hp,5); insertLastList(&hp,3); insertLastList(&hp,6); insertLastList(&hp,7); insertLastList(&hp,1); insertLastList(&hp,2); insertLastList(&hp,2); insertPosList(&hp,10,2); /*2 1 3 2 5 3 6 7 1 2 2 2 size = 12 */ travelList(hp); printf("size = %d\n",sizeList(hp)); #endif #if 1 printf("删除最后一个节点...\n删除第8个节点...\n删除第一个节点...\n"); deleteLastList(&hp); deletePosList(&hp,8); deleteFirstList(&hp); travelList(hp); printf("size = %d\n",sizeList(hp)); #endif #if 0 elemType *data = findList(hp,6); printf("查找 6 是否在链表中...结果:%d\n",*data); printf("取得链表中得第5个元素...结果:%d\n",getElem(hp,5)); printf("清空链表\n"); clearList(&hp); travelList(hp); printf("size = %d\n",sizeList(hp)); #endif #if 1 printf("删除链表中所有的1....\n"); deleteSameList(&hp, 1); travelList(hp); printf("size = %d\n",sizeList(hp)); #endif #if 1 printf("去除链表中得重复元素...\n"); deleteRepeatList(&hp); travelList(hp); printf("size = %d\n",sizeList(hp)); #endif system("pause"); return 0; }
************************************************************
运行结果:
************************************************************
2 1 3 2 5 3 6 7 1 2 2 2 size = 12 删除最后一个节点... 删除第8个节点... 删除第一个节点... 1 3 2 5 3 6 1 2 2 size = 9 删除链表中所有的1.... 3 2 5 3 6 2 2 size = 7 去除链表中得重复元素... 单链表空 3 2 5 6 size = 4 请按任意键继续. . .