注:使用了少部分的c++的引用,文件后缀名要为.cpp,不然会报错,若看起来有困难,引用改为指针也简单,不想改的就可以去看看c++引用的相关知识。
代码如下(只测试了部分功能):
#include<stdio.h>
#include<stdlib.h>
/*单链表的基本操作,增删改查...
如果功能有错误请指出,注释都写了我的思想,欢迎交流探讨 */
//定义节点
typedef struct LNode{
int data; //值域
struct LNode *next; //指针域
}LNode,*LinkList;
//增---1、头插法
int HeadInsert(LinkList &L){
int x = 0;
int length = 0;
LNode *S;
L = (LinkList)malloc(sizeof(LNode)); //头节点
L->next = NULL; //头节点指针域置空
scanf("%d",&x);
while(x!=886){
S = (LNode*)malloc(sizeof(LNode)); //开辟空间存新节点指针
S->data = x; //赋值给新节点的值域
S->next = L->next; //将头节点后面的赋给新节点(准确来说应该是节点指针,但这样说好理解)
L->next = S; //再将新的节点插入到头节点后(准确的来说是新节点的地址赋给了头节点的指针域)
length++; //记录新增的节点 ,实际上节点个数是length+1
scanf("%d",&x);
}
return length; //返回新添的节点个数 ,实际个数应为length+1个
}
//增--2、 尾插法
int EndInsert(LinkList &L){
int length = 0;
int x;
L = (LinkList)malloc(sizeof(LNode));
LNode *s,*r = L; //r为尾节点的指针,开始时尾结点和头节点在一个位置
scanf("%d",&x);
L->next = NULL; //头节点指针域置空
while(x!=886){
s = (LNode*)malloc(sizeof(LNode));//开辟空间存新节点的指针
s->data = x;
r->next = s; // 将新节点接在尾节点的后面
r = s; // 重置尾指针到尾部
length++; // 记录新增的节点
scanf("%d",&x);
}
r->next = NULL; //尾节点置空
return length;
}
//查 -- 1、按位查找
LNode *GetElemI(LinkList &L,int loc){
if(loc == 1){
return L; //若查找第一个节点即返回头节点
}
if(loc < 1){
return NULL;
}
LNode *p = L; //p用来存放找到的节点
int count = 1; //计数器
while(L->next!= NULL&&count<=loc - 1){
p = p->next; //存放节点
count++; //控制循环次数,根据个人习惯调整初始值和条件
}
return p; //返回该节点的指针
}
//查 -- 2、按值查找
LNode *GetElemII(LinkList &L,int value){
//按值查找不考虑头节点,头节点值域一般不存数据
int loc = 1; //初值设为1是因为还有头节点
LNode *p = L->next; //从新添加的节点开始
while(p->next!=NULL&&p->data!=value){
p = p->next;
loc++;
}
return p; //返回该节点的指针,若需要返回位置,修改函数类型为int,返回loc即可
}
//删--1 、遍历法
LNode *DeleteI(LinkList &L,int loc){
//在把头节点后的节点作为第一个节点的情况下(头节点通常不删,头节点为0号节点)
//loc位的节点是想删除节点的前一个节点,即loc为1,删掉的是第二个节点
if(loc<1){
return NULL; //表示删除失败
}
LNode *p = GetElemI(L,loc);
LNode *q = (LNode*)malloc(sizeof(LNode));
q = p->next; //这一步的q就是即将要删去的节点的指针
p->next = q->next;
return q; //返回被删去的节点的指针
}
//删--2、赋值法
int DeleteII(LinkList &L,LNode *p){
//参数中的p即为要删除的节点指针
LNode *q = (LNode*)malloc(sizeof(LNode));//开辟一个临时空间存结构体指针
q->data = p->next->data;
p->data = q->data; //将p下一个节点的值赋给p,相当于删去了p,有点儿偷天换日的意思
free(q); //释放q的占用空间
return 1;
}
//改
LNode *Change(LinkList &L,int value1,int value2){
LNode *p = GetElemII(L,value1); //找到值为value1的节点指针
p->data = value2; //将该节点的值改为value2
return p; //返回修改后的节点的指针
}
int main (){
int i;
int length_Head,length_End;
LinkList L = (LinkList)malloc(sizeof(LNode));
length_End = EndInsert(L); //尾插法
// length_Head = HeadInsert(L); //头插法
// for(i = 0;i<length_Head;i++){
// L = L->next; //先执行这一步是因为要跳过头节点。
// printf("%d\n",L->data);
// }
// free(L);
printf("---------------\n");
LNode *p = GetElemI(L,2); //第二个节点为第一个新添加的节点,第一个节点为头节点
printf("%d\n",p->data);
printf("---------------\n");
for(i = 0; i<length_End;i++){
L = L->next;
printf("%d\n",L->data);
}
return 0;
}