数据结构学习笔记
本篇实现了线性表及链表的各种操作,代码用vs2015编辑,线性表及链表各有两个文件,一个是供主函数调用的头文件,另一个是实现头文件里函数的源代码文件。
线性表
头文件
#pragma once
#include <malloc.h>
#define MAXSIZE 10
typedef int elemtype;
typedef struct sequlist
{
elemtype data[MAXSIZE];
int last;
}SequenList;
//线性表的初始化
SequenList *Init_SequenList();
//顺序表的长度
int SequenList_Length(SequenList *L);
//线性表指定位置的插入
int Insert_SequenList(SequenList *L, elemtype x, int i);
//线性表指定位置元素的删除
int Delete_SequenList(SequenList *L, int i);
//取数据元素
elemtype GetData(SequenList *L, int i);
//查找操作,查找与关键字Key相同的数据元素,若存在,返回下标
int Search_SequenList(SequenList *L, elemtype key);
//顺序表的遍历
int Print_SequenList(SequenList *L);
源代码文件
#pragma once
#include "List.h"
#include <stdio.h>
//线性表的初始化
SequenList *Init_SequenList()
{
SequenList *L;
L = (SequenList *)malloc(sizeof(SequenList));
if (L != NULL)
{
L->last = -1;
}
return L;
}
//顺序表的长度
int SequenList_Length(SequenList *L)
{
return (L->last + 1);
}
//线性表指定位置的插入
int Insert_SequenList(SequenList *L, elemtype x, int i)
{
int j;
if (L->last >= MAXSIZE - 1)
return 0;
if (i<1 || i>L->last + 2)
return -1;
for (j = L->last; j >= i - 1; j--)
L->data[j + 1] = L->data[j];
L->data[i - 1] = x;
L->last = L->last + 1;
return 1;
}
//线性表指定位置元素的删除
int Delete_SequenList(SequenList *L, int i)
{
if (i<1 || i>L->last + 1)
return 0;
for (int j = i; j<=L->last+1; j++)
L->data[j-1] = L->data[j ]; //第i个数据的下标对应i-1
L->last--;
return 1;
}
//取数据元素
elemtype GetData(SequenList *L, int i)
{
if (i<1 || i>L->last + 1)
return 0;
else
return L->data[i - 1];
}
//查找操作,查找与关键字Key相同的数据元素,若存在,返回下标
int Search_SequenList(SequenList *L, elemtype key)
{
int i = 0;
for (i = 0; i <= L->last + 1; i++)
if (L->data[i] == key)
return (i + 1);
return 0;
}
//顺序表的遍历
int Print_SequenList(SequenList *L)
{
int i;
if (L->last == -1)
return 0;
for (i = 0; i <= L->last; i++)
{
printf("a[%2d]=%4d\t", i + 1, L->data[i]);
if ((i + 1) % 5 == 0)
printf("\n");
}
}
链表
链表头文件
#pragma once
#include <stdio.h>
#include <stdlib.h>
typedef int elemtype;
//单链表节点类型定义
typedef struct node {
elemtype data;
struct node *next; //此结构体类型的指针
}LinkList; //单链表类型名为SLinkList
//双向链表节点类型定义
typedef struct dnode
{
elemtype data;
struct dnode *next, *prior;
}DLinkList;
//头插法建立带头结点的单链表函数
LinkList *Create_LinkListF();
//尾插法建立带头结点的单链表函数
LinkList *Create_LinkListR();
//单链表的遍历,返回Data
int Print_LinkList(LinkList *head);
//求单链表的长度
int LinkList_Length(LinkList *head);
//按序号查找单链表
LinkList *GetData_LinkList(LinkList *head, int i);
//按值查找单链表
LinkList *Search_LinkList(LinkList *head, elemtype key);
//单链表的后插运算
void InsertAfter_LinkList(LinkList *p, LinkList *s);
//单链表的前插运算
//若只考虑数据元素之间的逻辑关系,可以将s插入在p之后,然后在交换两者的数据域
void InsertBefore_LinkList(LinkList *head, LinkList *p, LinkList *s);
//在指定序号前插入运算
int InsertNo_LinkList(LinkList *head, LinkList *s, int i);
//删除p的后继节点s
int DeleteAfter_LinkList(LinkList *p);
//删除指定节点本身
int DeleteNode_LinkList(LinkList *head, LinkList *p);
//删除指定位置节点
int DeleteNo_LinkList(LinkList *head, int i);
//置空表
LinkList *SetNull_LinkList(LinkList *head);
源代码文件
#include "Link.h"
#include <stdio.h>
//头插法建立带头结点的单链表函数
LinkList *Create_LinkListF()
{
elemtype ix;
LinkList *head, *p;
head = (LinkList *)malloc(sizeof(LinkList));
if (head == NULL)
return head;
head->next = NULL;
printf("请输入数据直到输入0结束!\n");
scanf_s("%d", &ix);
while (ix!=0)
{
p = (LinkList *)malloc(sizeof(LinkList));
if (p == NULL)
return head;
p->data = ix;
p->next = head->next;
head->next = p;
scanf_s("%d", &ix);
}
return head;
}
//尾插法建立带头结点的单链表函数
LinkList *Create_LinkListR()
{
elemtype ix;
LinkList *head, *p, *tail;
head = (LinkList *)malloc(sizeof(LinkList));
if (head == NULL)
return head;
head->next = NULL;
tail = head;
printf("请输入数据直到输入0结束!\n");
scanf_s("d",&ix);
while (ix!=0)
{
p = (LinkList *)malloc(sizeof(LinkList));
if (p == NULL)
return head;
p->data = ix;
tail->next = p;
tail = p;
tail->next = NULL;
scanf_s("%d",&ix);
}
return head;
}
//单链表的遍历,返回Data
int Print_LinkList(LinkList *head)
{
LinkList *p = head->next;
if (p == NULL)
return 0;
while (p!=NULL)
{
printf("%d", p->data);
p = p->next;
}
return 1;
}
//求单链表的长度
int LinkList_Length(LinkList *head)
{
LinkList *p = head;
int j = 0;
while (p->next!=NULL)
{
p = p->next;
j++;
}
return j;
}
//单链表查找分为按序号查找和按值查找
//按序号查找单链表
LinkList *GetData_LinkList(LinkList *head, int i)
{
int LinkList_Length(LinkList *head);
if (i<1 || i>LinkList_Length(head))
return NULL;
LinkList *p;
int j=0;
p = head;
while (p->next!= NULL&&j<i)
{
p = p->next;
j++;
}
if (j == i)
return p;
else
return NULL;
}
//按值查找单链表
LinkList *Search_LinkList(LinkList *head, elemtype key)
{
LinkList *p;
p = head->next;
while (p!=NULL)
{
if (p->data == key)
break;
else
p = p->next;
}
return p;
}
//单链表的插入分为前插和后插
//单链表的后插运算
void InsertAfter_LinkList(LinkList *p, LinkList *s)
{
s->next = p->next;
p->next = s;
}
//单链表的前插运算
//若只考虑数据元素之间的逻辑关系,可以将s插入在p之后,然后在交换两者的数据域
void InsertBefore_LinkList(LinkList *head, LinkList *p, LinkList *s)
{
LinkList *q;
q = head;
while (q->next!=p)
{
q = q->next;
}
s->next = p;
q->next = s;
}
//在指定序号前插入运算
int InsertNo_LinkList(LinkList *head, LinkList *s, int i)
{
LinkList *GetData_LinkList(LinkList *head, int i);
void InsertAfter_LinkList(LinkList *p, LinkList *s);
LinkList *p;
if (i <= 0)
p = NULL;
else if (i == 1)
p = head;
else
p = GetData_LinkList(head, i - 1);
if (p == NULL)
{
return 0;
}
else
{
InsertAfter_LinkList(p, s);
return 1;
}
}
//单链表的删除
//删除p的后继节点s
int DeleteAfter_LinkList(LinkList *p)
{
if (!p)
return 0;
LinkList *s;
s = p->next;
if (!s)
return 0;
else
p->next = s->next;
free(s);
return 1;
}
//删除指定节点本身
int DeleteNode_LinkList(LinkList *head, LinkList *p)
{
int DeleteAfter_LinkList(LinkList *p);
LinkList *s;
if (p->next != NULL)
{
p->data = p->next->data;
return (DeleteAfter_LinkList(p));
}
else
{
s = head;
while (s->next!=p)
{
s = s->next;
}
return (DeleteAfter_LinkList(s));
}
}
//删除指定位置节点
int DeleteNo_LinkList(LinkList *head, int i)
{
LinkList *p, *r;
if (i <= 0)
p = NULL;
else if (i == 1)
p = head;
else
p = GetData_LinkList(head, i-1);
if (p == NULL)
return 0;
else
{
r = p->next;
if (r == NULL)
return 0;
p->next = r->next;
free(r);
return 1;
}
}
//置空表
LinkList *SetNull_LinkList(LinkList *head)
{
while (head->next)
DeleteAfter_LinkList(head);
return head;
}