问题描述
- C语言单链表的插入求解了
-
对于带有头结点的链表,为什么在插入方法需要传入头指针的地址(二重指针)?对于不带头结点的链表,插入或者删除第一个元素时,需要使用头指针的地址,可是对于带头结点链表,为何要呢?
解决方案
解决方案二:
C语言不像C++,没有引用参数,所以参数的形参被改变不能作用到实参上。
比如
void foo(int i)
{
i = 2;
}
int i = 1;
foo(i); // i还是1
为此,需要指针:
void foo(int* i)
{
*i = 2;
}
int i = 1;
foo(&i); // 这样i=2了
这里需要初始化一个指针,指针本身相当于那个i,改变指针的指针指向的对象,才能给一个新的指针。
解决方案三:
传入头节点的地址后,你在函数中改变链表在调用的地方也可以生效,但是如果直接传头节点,那么你就要在函数中return头节点,然后在调用处接收
解决方案四:
(原创)C语言单链表插入
单链表插入c语言实现
解决方案五:
这里配有测试代码,
插入删除操作仅仅传入头结点的地址(一重指针),
没有传入头指针的地址(二重指针),
这个程序测试过后没有问题,还请大家能够指导
#include
#include
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
//定义节点的结构体
struct Node{
ElemType data;
struct Node* next;
};
typedef struct Node Node;
Status ListInit(Node** L,int n);//单链表初始化函数
Status GetElem(Node* L,int i,ElemType e);//获取单链表指定位置的元素
Status ListInsert(Node L,int i,ElemType e);
Status ListDelete(Node* L,int i,ElemType e);
void printList(Node L);
int main(){
Node* L;
int q = 0;
ListInit(&L,2);//初始化出一个联邦
ListInsert(L,3,3);//链表三号位置插入一个元素
ListInsert(L,4,4);//链表四号位置插入一个元素
if(ListDelete(L,3,&q)==OK)//删除三号位置上的元素
printf("q==%d
",q);
printf("打印单链表的所有数据
");
printList(L);
return 0;
}
//单链表初始化函数
//创建带有N个结点的单链表
//所有数据域初始化为零
Status ListInit(Node** L,int n){
Node* head = (Node*)malloc(sizeof(Node));//申请内存来创建头结点
Node* p = NULL;
if(head==NULL)
return ERROR;
head->data = 0;
head->next = NULL;
L = head;
//用头插法来创建各节点
for(int i = 0;i<n;i++){
p = (Node)malloc(sizeof(Node));
p->data = 0;
p->next = (*L)->next;
(*L)->next = p;
}
return OK;
}
//传入带有头结点单链表的头指针(就是传入头结点的地址)
Status GetElem(Node* L,int i,ElemType e){
int j = 1;
Node p = L->next;//让p指向链表的第一个元素
while(p!=NULL && j
p = p->next;
j++;
}
//如果传入i的位置不对返回错误
//p==NULL说明所选择的位置超出链表的长度了
//j>i说明i==0
if(p==NULL||j>i)
return ERROR;
*e = p->data;
return OK;
}
//在单链表第i个元素的前面插入元素
//传入的是单链表的头指针的地址来的
//部分书籍这个函数的定义是
//Status ListInsert(Node** L,int i,ElemType e)
Status ListInsert(Node* L,int i,ElemType e){
Node* p = NULL;
int j;
p = L;//p指向连表的头结点了
j = 0;
while(p!=NULL && j
p = p->next;
j++;
}
//p==NULL说明所选择的位置超出链表的长度了
//j>i-1表示i
if(p==NULL || j>i-1){
return ERROR;
}
//如果能走到这一步
//说明p已经指向了第i-1个元素了
Node * s = (Node*)malloc(sizeof(Node));
s->data = e;
s->next = p->next;
p->next = s;
return OK;
}
/*
删除单链表第i个位置上的元素
有些数据这个函数的定义是
Status ListDelete(Node** L,int i,ElemType e)
/
Status ListDelete(Node L,int i,ElemType e){
Node p = L;//让P指向单链表头结点
Node* q = NULL;
int j = 0;
while(p->next!=NULL && j
p = p->next;
j++;
}
if(p->next==NULL || j>i-1)
return ERROR;
//走到这里说明P指向了第i-1个元素了
*e = p->next->data;
q = p->next;
p->next = p->next->next;
free(q);
return OK;
}
/*
打印链表里的所有元素
/
void printList(Node L){
L = L->next;//让L指向链表的第一个元素
while(L!=NULL){
printf("%d ",L->data);
L = L->next;
}
printf("
");
}