线性表
1、线性表是一种逻辑结构,表示一种一对一的逻辑关系,除首节点和尾节点,每个结点只有一个前驱结点和一个后继结点
2、两种实现的物理结构:顺序存储,链式存储
顺序表
1、定义:用一组地址连续的存储单元,一次存储线性表中的元素,使得逻辑位置相邻的元素物理位置也相邻。
2、特点:
顺序表元素的位序从1开始
顺序表可以随机访问,通过首地址和序列号找到指定元素的时间复杂度为O(1)
顺序表存储密度高,每个结点只存储数据元素
顺序表进行插入删除操作平均时间复杂度为O(n)
顺序表的一维数组可以静态分配也可以动态分配。
(一)静态分配
#include <iostream>
#include<stdlib.h>
#include<time.h>
#define SIZE 100
#define OK 1
#define ERROR 0
//静态存储
typedef struct {
int data[SIZE];
int length;
}SqlList;
//初始化表,构造一个空的线性表
int initList(SqlList &L){
L.length = 0;
return OK;
}
//求表长
int Length(SqlList L,int &len){
if(L.data == NULL){
return ERROR;
}
len = L.length;
return OK;
}
//利用随机数创建顺序表
int creatList(SqlList &L,int len){
if(L.data==NULL|| len<=0) return ERROR;
//srand(time(NULL));
for(int i = 0;i<len;i++){
L.data[i] = rand()%100+1;
}
L.length = len;
return OK;
}
//打印链表
int printList(SqlList L){
if(L.data==NULL) return ERROR;
for(int i = 0;i<L.length;i++){
printf("%4d",L.data[i]);
}
printf("\n");
return OK;
}
//在链表第i个元素插入元素
int insertList(SqlList &L,int i,int e){
if(L.data == NULL)
return ERROR;
if(i<1 || i>L.length+1)//插入位置不合法
return ERROR;
if(L.length>=SIZE)//存储空间已满
return ERROR;
for(int j = L.length;j>=i;j--){
L.data[j] = L.data[j-1];
}
L.data[i-1] = e;
L.length++;
return OK;
}
//删除链表第i个位置的元素,并返回元素的值
int deleteList(SqlList &L,int i,int &e){
if(L.data == NULL)
return ERROR;
if(i<1 || i>L.length+1)//删除位置不合法
return ERROR;
e = L.data[i-1];
for(int j=i;j<L.length;j++){
L.data[j-1] = L.data[j];
}
L.length--;
return OK;
}
//按位查找,获取表第i个位置的元素值
int getElem(SqlList L,int i,int &e){
if(L.data==NULL)
return ERROR;
if(i<1||i>L.length)
return ERROR;
e = L.data[i-1];
return OK;
}
//按值查找,在表中查找具有给定关键值的元素,只返回第一个匹配元素的位置
int LocateElem(SqlList L,int e,int &locate){
if(L.data==NULL)
return ERROR;
for(int i = 0;i<L.length;i++) {
if (L.data[i] == e) {
locate = i+1;
return OK;
}
}
locate = NULL;
return OK;
}
//判断线性表是否为空
bool isEmpty(SqlList L){
if(L.length == 0)
return true;
else
return false;
}
int main(){
//顺序表一般都是由数组实现的,并不是动态内存。
//根据进程空间的概念到函数退出或者程序结束的时候会自动释放。
//所以不用单独释放内存,增加开销
SqlList L;
initList(L);
int e = 0 ;
//创建表
creatList(L,10);
printList(L);
//插入表
insertList(L,3,1);
printList(L);
//删除表
deleteList(L,3,e);
printList(L);
printf("%d\n",e);
//按位查找
getElem(L,3,e);
printf("%d\n",e);
//按值查找
LocateElem(L,1,e);
printf("%d\n",e);
return 0;
}
(二)动态分配
参考博客:
http://blog.youkuaiyun.com/doudouwa1234/article/details/45840805
关于ifndef的用法
http://blog.youkuaiyun.com/mozha_666/article/details/79485105
链表
1、逻辑位置相邻,物理位置不一定相邻的线性表。
2、适合做插入删除操作
3、分类:单链表,双链表,区分依据是含有几个指针域
(一)单链表
#include<stdio.h>
#include<stdlib.h>
typedef int ELemType ;
typedef struct LNode{
ELemType data;
struct LNode *next;
}LNode,*LinkList;
//头插法创建单链表
LinkList createLinkListByHead(LinkList &L){
LNode *s;
int x;
//创建头结点
L = (LinkList)malloc(sizeof(LNode));
//初始化单链表
L->next = NULL;
scanf("%d",&x);
while(x!=9999){
//开辟新结点
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
L->next = s;
scanf("%d",&x);
}
return L;
}
//尾插法创建单链表
LinkList createLinkListByTail(LinkList &L){
LNode *s,*r;
int x;
//创建头结点
L = (LinkList)malloc(sizeof(LNode));
//初始化链表
L->next = NULL;
r = L;//设置一个尾指针
while(scanf("%d",&x) && x!=9999){
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;//r指向新的表尾结点
}
r->next = NULL;
return L;
}
//打印单链表
void printLinkList(LinkList L){
if(L->next == NULL){
printf("单链表为空\n");
return ;
}
LNode *s = L;
while(s->next!=NULL){
s = s->next;
printf("%4d",s->data);
}
printf("\n");
}
//按位查找 查找第i个位置的元素值
LNode * getElem(LinkList L,int pos){
if(pos<=0) return NULL;
int i = 1;
LNode *s = L->next;
while(s&&(i<pos)){
s = s->next;
i++;
}
return s;
}
//按值查找结点 和该节点的位置
int locateElem(LinkList L,int e){
if(L->next == NULL){
printf("链表为空,元素值不存在\n");
return 0;
}
LNode *s = L->next;
int pos = 1;
while(s){
if(s->data == e) return pos;
s = s->next;
pos++;
}
pos = 0;
return pos;
}
int main(void){
LinkList L;
//头插法
// printf("请输入数值\n");
// createLinkListByHead(L);
// printLinkList(L);
//尾插法
printf("请输入数值\n");
createLinkListByTail(L);
printLinkList(L);
int pos = 0;
LNode *s = getElem(L,pos);
if(s){
printf("第%d个元素值是%d\n",pos,s->data);
}
else{
printf("第%d个元素值不存在\n",pos);
}
pos = locateElem(L,5);
if(pos){
printf("位置%d\n",pos);
}
else{
printf("不存在\n",pos); bgh
}
return 0;
}
(二)双链表
这里写代码片
(三)循环单链表
这里写代码片
(四)循环双链表
这里写代码片