接着上一篇,本篇来说一下如何对链表进行操作。
创建链表
现在已经可以通过malloc或者new来获得若干个零散的结点,接下来就是把这些零散的结点链接起来。很简单,只要把每个结点的next指针指向下一个结点的地址就行了。代码如下:
//定义结构体已经在上一篇文章中写过了,这里就直接用了
ndoe* node1 = new node;
ndoe* node2 = new node;
ndoe* node3 = new node;
ndoe* node4 = new node;
ndoe* node5 = new node;
node1->data = 5;//数据域赋值
node1->next = node2;
node2->data = 3;
node1->next = node3;
node3->data = 6;
node1->next = node4;
node4->data = 1;
node1->next = node5;
node5->data = 2;
node1->next = NULL;
这这做法虽然看起来很明了,但是有点冗长,所以咱们用for循环来实现吧。
#include<stdio.h>
#include<stdlib.h>
strcut node{
int data;
node* next;
};
//创建链表
node* create(int array[]){
node *p,*pre,*head;
head = new head; //创建头结点
head->next = NULL; //指针域置为空
pre = head; //pre记录头结点
for(int i=0;i<5;i++){
p = new node; //新建结点
p->data = array[i]; //给其数据域赋值
p->next = NULL; //新建结点的指针域为NULL
pre->next = p; //前驱结点的指针域设置为当前新建结点的地址
pre = p; 把pre设置为p,作为下个结点的前驱结点
}
return head; //返回结点头指针
}
int main(){
int array[5] = {5,3,6,1,2};
node* L= create(array); //新建链表,返回头指针head赋值给L
L= L->next;
while(L != NULL){
printf("%d",L->data); //输出每个结点的数据域
L = L->next;
}
return 0;
}
查找元素
如果有一了一条链表,那么如何查找其中是否有给定的元素x呢?很简单,只需从第一个结点开始,不断判断当前结点的数据域是否等于x,如果等于,那么就给计数器count加1,这样到达链表结尾时,count的数值就是链表中元素x的个数。
//再以head为头结点的链表上计数元素x的个数
int search(node* head,int x){
int count = 0;
node* p = head->next; //从一个结点开始
while(p != NULL){ //只要没有到达链表末位
if(p->data == x){
count++; //相等则加一
}
p = p->next;
}
return count; //返回计数器count
}
上面这部分代码可以直接写在“创建链表”部分的代码中进行使用,把create函数返回的头指针直接作为第一个和参数传入即可。
插入元素
对链表来说插入元素是指在链表给定位置的地方插入一个结点。例如在链表5,3,6,1,2的第三个位置插入元素4,就会使链表变为5,3,4,6,1,2。有人会问所谓的第i个位置插入元素是插入在这个位置之前还是之后,即上面这个例子最后会形成5,3,6,4,1,2还是5,3,4,6,1,2。事实上,在第三个位置插入元素4的意思是指在插入完成之后第三个位置的元素就是4,所以应该把第三个位置开始的元素让出来给需要插入的数,如下图
删除元素
对链表来说,删除元素是指删除;链表上所有值为给定的数x,例如删除5,3,6,1,2中的6,就会使链表变为5,3,1,2如下图
删除操作是这样进行的:
1.由指针变量p枚举结点,另一个指针变量pre表示p指向结点的前驱结点。
2.当p所指的结点恰好为x时,进行下面三个操作:
(1)令pre所指结点的指针域next指向p所指的下一个结点
(2)释放p所指的结点的内存空间
(3)令p指向pre所指结点的下一个结点
//删除head为头结点的链表中所有数据域为x的结点
void del(node* head,int x){
node* p = head->next; // p从第一个结点开始枚举
node* pre = head;
while(p != NULL){
if(p->data == x){
pre->next = p->next;
delet(p);
p = pre->next;
}else{
pre = p;
p = p->next;
}
}
}
这部分代码可以直接写在“创建链表”部分的代码中使用,把create函数返回头指针L直接作为第一个参数传入即可,