C语言-数据结构与算法
C语言基础
因为之前写算法都是用C++,也有了些C++基础,变量常量数据类型就跳过去吧。
首先是环境,学C++时候用Clion,C语言也用它写吧~
新建项目,选C执行文件,语言标准。。。就先默认C99吧,反正是测试环境,应该问题不大
直接运行一手
嗯。。JB家的新UI。。真是。。。。。。。一言难尽
指针
好像最开始学C++开始,就一直没玩明白指针,毕竟一用数组链表就直接上STL库,也不太用得到指针
新的学习阶段,从指针开始!
#include <stdio.h>
int main() {
int a = 123;
int * p = &a;
printf("a:%d\n", a);
printf("*p:%d\n", *p);
printf("a的地址:%p\n", &a);
printf("指针p指向的地址:%p\n", p);
printf("指针p自身的地址:%p\n", &p);
return 0;
}
如果你的Clion输出乱码,按照以下顺序配置即可解决:
文件——设置——编辑器——文件编码,都改成UTF-8
然后点击确定,回到代码页面,点击最下方UTF-8,选择GBK
再点击转换,重新运行即可解决
结构体
使用typedef可以给结构体指定别名
#include <stdio.h>
#include <string.h>
typedef struct Book {
char isbn[50];
char name[20];
int price;
}B;
int main() {
// 声明
struct Book b;
// 初始化
b.price = 20;
strcpy(b.name, "笑场");
// 声明同时初始化
struct Book a = {"122333123", "冷玚", 45};
B c = {"122334233123", "乡土中国", 65};
return 0;
}
属性声明的同时进行变量声明
struct Book {
char isbn[50];
char name[20];
int price;
} stu;
属性声明的同时进行变量声明及初始化
struct Book {
char isbn[50];
char name[20];
int price;
} stu = {"1531", "宇宙超度指南", 46};
如果只需要声明一次,可以省略结构体标记
struct {
char isbn[50];
char name[20];
int price;
} stu = {"1531", "宇宙超度指南", 46};
链表
链表结构体定义
typedef struct node {
int data;
struct node *next;
} node;
创建单链表
node *createList() {
node *head = (node *) malloc(sizeof(node));
if (head == NULL) return NULL; // 若内存申请失败,指针会为空(一般情况下不会申请失败)
head->data = 0;
head->next = NULL;
return head;
}
头结点:头指针指向的结点
首元结点:头结点后面的第一个结点
插入新结点
插入新结点的时候要注意,一定先抓住后边的那个结点,再修改前边的那个结点的指针指向。
(必须时刻有指针指向后边结点的位置,不能让后边的结点丢了😉)
删除指定位置结点
node *deleteNode(node *head, int pos) {
node *currentNode = head;
// 如果插入位置比链表长,为非法操作。(头结点data存储链表长度)
if (pos > currentNode->data) return NULL;
for (int i = 0; i < pos; ++i) {
currentNode = currentNode->next;
}
node *temp = currentNode->next;
currentNode->next = currentNode->next->next;
// 释放内存
free(temp);
// 链表长度减一
head->data--;
return head;
}
输出链表
void printList(node *head) {
// 跳过头结点数据
node *currentNode = head->next;
while (currentNode != NULL) {
if (currentNode->next == NULL) {
// 是最后一个结点的话不输出箭头
printf("%d", currentNode->data);
} else {
printf("%d->", currentNode->data);
}
currentNode = currentNode->next;
}
printf("\n");
}
测试链表相关方法
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
} node;
// 创建单链表
node *createList() {
node *head = (node *) malloc(sizeof(node));
if (head == NULL) return NULL;
head->data = 0;
head->next = NULL;
return head;
}
// 插入新结点
node *insertNode(node *head, int data, int pos) {
node *currentNode = head;
// 如果插入位置比链表长,为非法操作。(头结点data存储链表长度)
if (pos > currentNode->data) return NULL;
for (int i = 0; i < pos; ++i) {
currentNode = currentNode->next;
}
// 新建结点
node *newNode = (node *) malloc(sizeof(node));
newNode->data = data;
// 牵住当前位置下一个结点
newNode->next = currentNode->next;
// 牵住当前位置上一个结点
currentNode->next = newNode;
// 链表长度加一
head->data++;
return head;
}
// 删除结点
node *deleteNode(node *head, int pos) {
node *currentNode = head;
// 如果插入位置比链表长,为非法操作。(头结点data存储链表长度)
if (pos > currentNode->data) return NULL;
for (int i = 0; i < pos; ++i) {
currentNode = currentNode->next;
}
node *temp = currentNode->next;
currentNode->next = currentNode->next->next;
// 释放内存
free(temp);
// 链表长度减一
head->data--;
return head;
}
// 遍历列表
void printList(node *head) {
// 跳过头结点数据
node *currentNode = head->next;
while (currentNode != NULL) {
if (currentNode->next == NULL) {
// 是最后一个结点的话不输出箭头
printf("%d", currentNode->data);
} else {
printf("%d->", currentNode->data);
}
currentNode = currentNode->next;
}
printf("\n");
}
int main() {
node *l = createList();
insertNode(l, 1, 0);
insertNode(l, 2, 1);
insertNode(l, 3, 0);
printList(l);
deleteNode(l, 1);
printList(l);
return 0;
}