数据结构-链表
一、什么是链表
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表这种存储方式,其元素个数是不受限定的,当进行添加元素的时候存储的个数就会随之改变。
二、链表的分类
- 循环 -带头/不带头--单链表/双向链表
- 非循环 -带头/不带头--单链表/双向链表
typedef struct LNode { int data; strruct LNode *next; }LinkNode;
此处LinkNode 为变量名。
struct LNode { int data; strruct LNode *next; }LinkNode;
此处LinkNode 为类型名。
三、单链表特点
访问下一个元素后没法访问他的前驱。
四、单链表的基本操作———初始化,插入、删除、遍历、查询。
1.准备工作
头文件
#include "stdio.h" #include "stdlib.h" //提供malloc()和free() #include "string.h" //提供strcpy()等
malloc函数:动态内存分配函数
分配类型 *)malloc(分配元素个数 *sizeof(分配类型))
如果成功,则返回该空间首地址,该空间没有初始化,如果失败,则返回0
a=(char*)malloc(100*sizeof(char));
free函数
free ()
free的功能:释放ptr指向的存储空间。被释放的空间通常被送入可用存储区池,以后可在调用malloc、realloc以及calloc函数来再分配。
就是说free掉以后,可以这段内存就可以被再分配,但是不会清空内容。
地址是不可能被删掉的,free只是告诉系统,这块内存不需要了,系统可以拿来做别的事。这块内存被释放之后暂时还没有其他程序访问这块内存,所以之前的数据还在,读也能读出来,但这样是不安全的,这次是这个结果,下一次就不一定了。c要求严谨,释放之后的内存就不要再用了
2.基本操作
创建结构体
struct Node { int a;//数据域 struct Node* next; //指针域 } ;
全局定义链表头尾指针,方便调用
struct Node *head =NULL; struct Node *end=NULL;
#include <iostream> #include <cstdio> #include <stdlib.h> using namespace std; typedef int ElemType; typedef struct Node //用结构体定义结点 { ElemType data; struct Node *next; }Node, *LinkedList; //把struct Node *定义为新类型LinkList,是一个结构体的指针。 void InitLinkedList() //初始化 { Node* L; //定义一个头结点 L = (Node *)malloc(sizeof(Node));//头结点申请地址 if (L == NULL) printf("申请空间失败"); L->next = NULL; } LinkedList CreateLinkedListHead(int n)//头插法 { int i; int x; Node *L; L = (Node *)malloc(sizeof(Node)); L->next = NULL; printf("输入元素:"); for (i = 0; i<n; i++) { Node *p; //要插入的结点 p = (Node *)malloc(sizeof(Node)); scanf("%d", &x); p->data = x; p->next = L->next; L->next = p; } return L; } LinkedList CreateLinkedListTail(int n)//尾插法 { int x; Node *L; L = (Node *)malloc(sizeof(Node)); L->next = NULL; Node *r; r = L; printf("输入元素:"); while (n--) { scanf("%d", &x); Node *p; p = (Node *)malloc(sizeof(Node)); p->data = x; r->next = p; r = p;//之后的循环遇到r就是等同于p r->next就是p->next } r->next = NULL; return L; } void InsertLinkedList(LinkedList L, int i, ElemType x)//插入元素 i为插入位置 x为插入元素 { LinkedList p; p = L;//把链表的头结点赋值给p int j; j = 1; while (j<i) { p = p->next; j++; } Node *s; //定义插入的结点 s = (Node *)malloc(sizeof(Node)); s->data = x; s->next = p->next; p->next = s; } void output(LinkedList L)//遍历 { Node *p; for (p = L->next; p != NULL; p = p->next) { printf("%d", p->data); } } void deleteLinkedList(LinkedList L, int i)//删除i位置上的元素 { int j; LinkedList p, q; p = L; j = 1; while (j<i) { p = p->next; j++; } q = p->next; p->next = p->next->next; free(q); } int GetElem(LinkedList L, int i)//获取元素 { ElemType e; int j; LinkedList p; p = L->next; j = 1; while (p && j<i) { p = p->next; j++; } if (!p || j > i) { printf("第%d个节点不存在\n", i); return 0; } else e = p->data; return e; } int getlength(LinkedList L)//求单链表长度(遍历了) { LinkedList p; int length = 0; p = L->next;//p指向第一个节点; while (p) { printf("单链表的数据为%d\n", p->data); length++; p = p->next; } return length; } void ClearList(LinkedList L) { LinkedList p, q; p = L->next; while (p) { q = p->next; free(p); p = q; } L->next = NULL; } int main() { int n; int i; int x; LinkedList H; printf("输入单链表的长度(头插法):"); scanf("%d", &n); H = CreateLinkedListHead(n); output(H); printf("\n"); printf("输入单链表的长度(尾插法):"); scanf("%d", &n); H = CreateLinkedListTail(n); output(H); printf("\n"); printf("单链表长度为%d", getlength(H)); printf("\n"); printf("输入要获取哪一位置的元素:"); scanf("%d", &i); printf("%d\n", GetElem(H, i)); printf("输入要插入的元素e与位置i:"); scanf("%d %d", &x, &i); InsertLinkedList(H, i, x); output(H); printf("\n"); printf("输入要删除哪一位置上的元素:"); scanf("%d", &i); deleteLinkedList(H, i); output(H); printf("\n是否要整表删除1/0?\n"); scanf("%d", &x); if (x == 1) { ClearList(H); printf("单链表为:"); output(H); } else { printf("单链表仍为:"); output(H); } system("pause"); return 0; }
浙公网安备 33010602011771号