数据结构—单链(无头结点)
关于数据结构,我个人觉得就是对结构体、数组等这些数据存储的灵活运用。然后把包装好的这些结构,我们要明白她的实现,就算是初步的掌握了数据结构。
-
#### 结构体定义
首先还是从结构体定义说起,说起结构体定义就让我想起了这次注释中的struct
#pragma once
typedef int Data_;
typedef struct SNode{
Data_ data;
struct SNode* next; //这里刚开始写的是 SNode* next; 就这一处代码,产生了100多条错误报告
}SNode;
typedef struct SList{
SNode* _head;
}SList;
就因为这里的这里的struct,不到100行的代码,错误报了100多行,很惊人。这时候调试都没办法调试。
这里的struct,可以是看做编译器的编译顺序上的bug,其实也不算bug,而是我对编译顺序掌握不好,误以为typedef struct SNode{
}SNode之后的SNode就可以和struct SNode替换,导致我在注释位置没有使用struct标记,所以出错。
-
##### 注意初始化单链
这次写这个代码时,发现始终链尾读数,或者是循环截止不正确,查找了半天,才发现是因为刚开始创建链表就么有初始化,也就是第一个节点的next没有NULL。
-
##### VS2013的调试
掌握正确的调试手段,对我们程序员的幸福感是有很大提升的。对于这次的代码实现,我就发现还是要知道vs 的调试快捷键才是提升幸福感的有效途径。
编译并运行 | F5 |
---|---|
只编译 | Ctrl+F5 |
断点 | Alt+F9 |
切换断点 | F9 |
逐过程运行 | F10 |
逐语句运行 | F11 |
下面就是单链的实现了
头文件,Slist.h
#pragma once
typedef int Data_;
typedef struct SNode{
Data_ data;
struct SNode* next;
}SNode;
typedef struct SList{
SNode* _head;
}SList;
//对链表
//增,(任意位置插入,尾插,用于初始化, 头插)
//删,
//查,
//改,
//清空,
//销毁,
//打印
void Inint();
void HeadInsert();
void EndInsert();
void Insert();
void Delect();
void Find_();
void UpData();
void ClearData();
void Destory();
void Print();
主文件SList.c
#include"Slist.h"
#include<assert.h>
#include<stdlib.h>
#include<stdio.h>
// 不带头指针的单链表
void Inint(SList* list){
list->_head = NULL;
}
// 头插
void HeadInsert(SList* list ,Data_ data){
assert(list);
SNode* tmp;
if (list->_head == NULL){
tmp = (SNode*)malloc(sizeof(SNode));
tmp->data = data;
tmp->next = NULL;
list->_head = tmp;
}
else{
tmp = (SNode*)malloc(sizeof(SNode));
tmp->data = data;
tmp->next = list->_head;
list->_head = tmp;
}
}
//尾插
void EndInsert(SList* list, Data_ data){
assert(list);
SNode* tmp;
SNode* pEnd= NULL; //TODO 使用了可能未初始化的本地指针变量“pEnd”
if (list->_head == NULL){
tmp = (SNode*)malloc(sizeof(SNode));
tmp->data = data;
tmp->next = NULL;
list->_head = tmp;
}
else{
tmp = list->_head;
while (tmp->next){
tmp = tmp->next;
pEnd = tmp;
}
tmp = (SNode*)malloc(sizeof(SNode));
tmp->data = data;
tmp->next = NULL;
pEnd->next = tmp;
}
}
void Insert(SList* list, SNode* node, Data_ data){
assert(list);
if (list == NULL){
}
}
//删除
void Delect(SList* list, Data_ data){
assert(list);
SNode* tmp;
SNode* find_data = NULL;
tmp = list->_head;
if (tmp == NULL){
printf("没有可以删除的数据\n");
return;
}
while (tmp != NULL){
if (tmp->next->data == data){
find_data = tmp->next;
tmp->next = tmp->next->next;
free(find_data);
return;
}
tmp = tmp->next;
}
printf("该数据不存在\n");
}
//查找
void Find_(SList* list, Data_ data){
assert(list);
SNode* tmp;
tmp = list->_head;
while (tmp){
if (tmp->data == data){
printf("要查找的数据%d在链表中\n", data);
break;
}
tmp = tmp->next;
}
}
// 更新
void UpData(SList* list, Data_ origin, Data_ data){
assert(list);
SNode* tmp;
tmp = list->_head;
while (tmp){
if (tmp->data == origin){
tmp->data = data;
printf("已经将%d修改成%d!!!\n",origin,data);
return;
}
tmp = tmp->next;
}
printf("没有该数据,修改错误!!\n");
}
// 清空
void ClearData(SList* list){
assert(list);
SNode* tmp;
tmp = list->_head;
while (tmp){
tmp->data = 0;
tmp = tmp->next;
printf("已经将所有的数据全部清空成0\n");
}
}
// 销毁
void Destory(SList* list){
assert(list);
SNode* tmp;
SNode* destory_;
tmp = list->_head;
while (tmp){
destory_ = tmp;
tmp = tmp->next;
free(destory_);
}
list->_head = NULL;
}
// 打印
void Print(SList* list){
assert(list);
if (list->_head == NULL){
printf("词表为空!!\n");
return;
}
SNode* tmp = list->_head;
while (tmp != NULL){
printf("%d\n", tmp->data);
tmp = tmp->next;
}
}
int main(){
SList s;
Inint(&s);
HeadInsert(&s, 1);
HeadInsert(&s, 4);
HeadInsert(&s, 56);
EndInsert(&s, 9);
Delect(&s, 4);
Find_(&s, 56);
UpData(&s, 9, 33);
Print(&s);
Destory(&s);
Print(&s);
system("pause");
return 0;
}