#include <stdio.h>
#include <stdlib.h>
typedef struct LNode{
int data;
struct LNode *next;
}LNode ,*LinkList;
//链表初始化(带头结点)
bool InitList (LinkList &L){
L = (LNode *)malloc(sizeof(LNode));
L->next = NULL;
return false;
}
//插入
bool InsertList (LinkList &L, int i, int e){ //需要传入的参数,链表,插入的位置,插入的元素
LNode *p = L; //创建一个指针指向首元结点
LNode *s = (LNode *)malloc(sizeof(LNode)); //为要插入的新结点申请空间!!!
int j=0;
while(p&&j<i-1){ //查找第i个元素
p=p->next;
j++;
}
if(!p||j>i-1){ //插入位置必须合法
return false;
}
s->next = p->next; //插入结点
s->data = e;
p->next = s;
return true;
}
//删除
bool DeleteList (LinkList &L,int n){
LNode *p=L;
int j=0;
while(p->next&&j<n-1){
p=p->next;
j++;
}
if(!p->next||j>n+1){
printf("删除位置输入不合法\n");
return false;
}
// p->next = p->next->next; 至此结点修改完成,但是删除结点需要释放被删除结点的空间,所以需要先保留一下被删除节点的地址
LNode *q=NULL;
q=p->next;
p->next=q->next;
free(q); //free会释放自己和自己所指区域的空间,所以传的参数是被删除节点的地址
return true;
}
//取值
bool GetList(LinkList L,int n , int &e){
LNode *p = L->next;
int j=1;
while(p&&j<n){
p=p->next;
j++;
}
if(!p||j>n){
printf("取值位置输入不合法\n");
return false;
}
e = p->data;
return true;
}
//按值查找
int LocateElement(LinkList L,int e){
LNode *p = L->next;
int j =1;
while(p){
if(p->data== e){
return j;
}
p=p->next;
j++;
}
return NULL;
}
//输出
bool PrintfList (LinkList L){
LNode *p = L->next;
while(p){
printf("%d",p->data);
p=p->next;
}
return true;
}
int main(){
LinkList L; //头指针
InitList(L); //初始化
//插入 表名,位置, 值
InsertList(L,1,1);
InsertList(L,2,2);
InsertList(L,3,3);
//按值查找 (返回的是位序,书上写的是返回一个结点)
printf("元素1在链表第%d位\n",LocateElement(L,3));
//取值
int e=NULL,c=NULL;
GetList(L,1,e);
// GetList(L,5,c);
printf("查找到第1位的值为%d\n",e);
printf("查找到第2位的值为%d\n",c);
// 删除(删除指定位置的值) //表名,位置
DeleteList(L,2);
DeleteList(L,2);
//输出
PrintfList(L);
return 0;
}
心得:(1)分清楚结点类型的指针和结点
结点类型的指针,用来存放指向这种类型结点的地址,结点类型名*shen。
结点,是结点这种变量,malloc申请。
(2)为了使写出来的函数方便别人使用,或者主代码调用,一定要有较好健壮性。
判断传入参数是否正确,返回值是什么类型,是什么。都要很明确。