我们知道数据结构的储存结构(也称物理结构)分为顺序储存结构和链式储存结构,这两种结构的代表分别是顺序表和单链表,两种储存结构各有优劣,前面简单学习了顺序表,今天让我们看看单链表又是怎样对数据进行处理的。代码如下:
#include<stdio.h>
#include<malloc.h>
typedef struct Linknode{
char data;
struct Linknode *next;
}LNode, *NodePtr;
//定义结构体变量
NodePtr initLinklist(){
NodePtr head=(NodePtr)malloc(sizeof(LNode));
head->data='\0';
head->next=NULL;
return head;
}
//初始化头节点
void printList(NodePtr head){
NodePtr p=head->next;
if(p==NULL)printf("The list does not exist!");
while(p!=NULL){
printf("%c",p->data);
p=p->next;
}
printf("\r\n");
}
//打印单链表
void appendElement(NodePtr head,char Data){
NodePtr p,q;
q=(NodePtr)malloc(sizeof(LNode));
q->data=Data;
q->next=NULL;
p=head;
while(p->next!=NULL){
p=p->next;
}
p->next=q;
}
//初始化单链表,将元素逐一插入
void insertElement(NodePtr head,char Data,int position){
NodePtr p,q;
p=head;
int i;
for(i=0;i<position;i++){
p=p->next;
}
if(p==NULL){
printf("The position %d is beyond the scope of the list.",position);
return;
}
q=(NodePtr)malloc(sizeof(LNode));
q->data=Data;
printf("linking\r\n");
q->next=p->next;
p->next=q;
}
//在单链表指定位置插入元素
void deleteElement(NodePtr head,char Data){
NodePtr p,q;
p=head;
while((p->next!=NULL)&&(p->next->data!=Data)){
p=p->next;
}
if(p->next==NULL){
printf("Cannot delete %c\r\n",Data);
return;
}
q=p->next;
p->next=p->next->next;
free(q);
}
//删除单链表中的指定元素
void appendInsertDeleteTest(){
NodePtr head=initLinklist();
printList(head);
appendElement(head,'H');
appendElement(head,'e');
appendElement(head,'l');
appendElement(head,'l');
appendElement(head,'o');
appendElement(head,'!');
printList(head);
deleteElement(head,'e');
deleteElement(head,'a');
deleteElement(head,'o');
printList(head);
insertElement(head,'o',1);
printList(head);
}
//测试样例
void basicAddressTest(){
LNode tempNode1,tempNode2;
tempNode1.data=4;
tempNode1.next=NULL;
tempNode2.data=6;
tempNode2.next=NULL;
printf("The first node: %d, %d, %d\r\n",&tempNode1,&tempNode1.data,&tempNode1.next);
printf("The second node: %d, %d, %d\r\n",&tempNode2,&tempNode2.data,&tempNode2.next);
tempNode1.next=&tempNode2;
}
//打印地址
int main(){
appendInsertDeleteTest();
basicAddressTest();
return 0;
}
//主函数
代码运行结果如下:
以上代码实现了对单链表的创建以及对单链表中指定元素的删除和向单链表指定位置插入元素等简单功能。
收获总结:
通过这次对于单链表的学习,让我了解到了单链表相较与顺序表的优势以及劣势。
优点:
1.链表的内存空间不连续。
2.如果知道要处理节点的前一个位置,则进行插入和删除的复杂度为O(1);如果不知道要处理节点的前一个位置,则进行插入和删除的复杂度为O(N)。
3.头插、头删的效率高,时间复杂度是O(1)。
4.没有空间限制,不会溢出,可以存储很多元素。
缺点:
链表不支持随机访问,查找元素效率低,需要遍历节点,时间复杂度是O(n)。
在进行代码的编写的时候,我觉得闵帆老师的这段代码进行优化。
/**
* Print the list.
* @param paraHeader The header of the list.
*/
void printList(NodePtr paraHeader){
NodePtr p = paraHeader->next;
while (p != NULL) {
printf("%c", p->data);
p = p->next;
}// Of while
printf("\r\n");
}// Of printList
这样写的话,对于没有元素的单链表无法进行判断,从而只会换行,可以添加一个判断语句来对特殊情况进行判断,当没有元素时,输出“The list does not exist”,有利于对代码的阅读和理解,修改代码如下:
void printList(NodePtr head){
NodePtr p=head->next;
if(p==NULL)printf("The list does not exist!");
while(p!=NULL){
printf("%c",p->data);
p=p->next;
}
printf("\r\n");
}
关于append,insert,delete函数的原理,可以用以下图示来表示(个人看法,可能出错):
1.append函数:
2.insert函数:
3.delete函数:
以上就是我的收获及总结。