c语言手写单链表实现,数组和链表结构对比小结和个人理解

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:09   2494   0

单链表是最简单的链表数据结构,A->B->C->D...一层链接一层,而理解单链表我个人觉得其实理解单链表对于双链表和循环链表其实原理是一样的。双链表好处是前后都有指针互相指向对方一前一后。循环链表是多了个头部和尾部,把整个链表都闭环了起来。

ac1fc93843aa85a2b87b2176f067ad8ad79.jpg

(1)对于链表的数据结构,因为它是指针一个指向一个,可以灵活的把内存的应用起来,而不是一个大数组,申请的是一堆完全连续的内存,对于链表我们还可以起到节省内存的作用,数组在确定之前,你必须自己固定的吧,而我们链表可以自己去无限去拓展,内存可以不连续。甚至于其实联想现实世界中,我们的光盘是不圆的,如果我们硬盘存储的数据要求的都是连续的,那就可能会遇到边界尴尬了,所以我个人理解是链表的意义其实重大,记得搜过资料,我们有些存储就是基于像类似于链表的存储结构的,比如二叉链表结构。其实都是对于指针一个灵活应用的一个算法变种。个人理解,说的不好,不喜勿喷。

(2)数组对于查询来说,有个通过下标直接查询很快,而链表就不支持下标查询了,查询稍微慢一些,这儿还没理解完全透彻,个人理解是指针是移动一个一个去查找,相对来说比较慢。

(3)对于插入删除来说,我们来比较下,数组是一个完全连续的内存,我们在插入或删除的时候,是不需要找到先对应的一个地方,然后再计算需要拓展的内存,给新的数组元素开辟新的内存,然后先把对应的值赋值给对应的下标而其他值是一个一个重新赋值进去。删除有点同理。 而链表则不需要,直接插入(或单链表是直接插入到它的屁股后面),删除只需要指针一个一个移动查找,找到对应的值删除,并把删除的前面和后面链接起来就可以。这个应该就是我们指针好用之处吧。

附个人写的简陋代码:

#include<stdio.h>
#include<stdlib.h>
typedef struct Node;
#define true 1
#define false 0
typedef int bool;

typedef struct Node{
int data;
struct Node* next;
} node;

/*释放链表内存*/
void freeNodeList(node *root){
if (root == NULL){
return;
}
node *temp = root;
while(temp != NULL){
node* ftemp;
ftemp = temp;
temp = temp->next;
free(ftemp);
}
}


void printNode(node *root){
if (root == NULL){
return;
}

node *temp = root;
while (temp != NULL){
printf("%d\n", temp->data);
temp = temp->next;
}
}
//插入链表元素进入到链表中
void insertNode(node *element ,node *root){
node *lastE = LastElement(root);
//其实这儿有个思考,如果element 它也是一串链表,其实完全可以合并的,暂时没去测试,我觉得是可以,结构体里面都是封装都是同样的结构体。
lastE->next = element;
}

node* LastElement(node *root){
if (root == NULL){
return NULL;
}
if (root->next == NULL){
return root;
}
node *temp = root;
node *pre;
pre = NULL;
while (temp != NULL){
pre = temp;
temp = temp->next;
if (temp == NULL){
break;
}
}
return pre;
}

/**
删除链表中指定的元素
*/
bool deleteNote(node *root, int data){//*node 是指针指向的是一个内存的地址门牌号,而如果是data是int,一般是存在栈变量,函数完毕就直接回收了。
bool isHasElement = false;
if (root == NULL){
return false;
}
node *temp = root;
node *pre;
pre = NULL;
while (temp != NULL){
if (temp->data == data){
//如果删除元素在第一个
if (pre == NULL){
node* froot = root;
root = root->next;
free(froot);
}
else{
pre->next = temp->next;
node* ftemp = temp;
free(ftemp);
}
printf("%s", "delte");
//如果删除元素在最后一个

//如果删除元素在中间
break;
}
pre = temp;
temp = temp->next;
}
return isHasElement;
}

int main(){
node *root;
root = malloc(sizeof(node));
if (root == NULL){
printf("%s", "root apply memory result is NULL");
return;
}
printf("address %02x\n", &(*root));
root->data = -1;
root->next = NULL;
node *temp = root;
printf("%d\n", root->data);
for (int i = 0; i < 100; i++){
node *next;
if ((next = malloc(sizeof(node))) != NULL){
next->data = i;
temp->next = next;
next->next = NULL;
temp = next;
printf("temp address2 %02x\n", &(*temp));
}

}
printf("address2 %02x\n", &(*root));
deleteNote(root, 10);
deleteNote(root, 20);
deleteNote(root, 30);
deleteNote(root, 90);

node *lastE = LastElement(root);
printf("\n%d\n", lastE->data);

printNode(root);
freeNodeList(root);
//printNode(root);
system("pause");
return 0;
}


///*排序*/
//void sort(node *root){
// int count = size(root);
// for (int i = 0; i < count; i++){
//
// }
//}
/**获取链表总数*/
int size(node *p){
if (p == NULL){
return;
}
int count = 0;
node* temp = p;
if (temp != NULL){
count++;
temp = temp->next;
}
return count;
}

bool isEmpty(node* root){
bool isEmpty = false;
if (root==NULL){
isEmpty = false;
}

return true;
}

转载于:https://my.oschina.net/u/3318187/blog/2050306

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP