这学期有安排数据结构的课程,不过内容安排上有些少,剩下很多时间来准备考研
接下来是整理一些之前上机课的内容(开始使用C语言编写,后来用C++类分装数据和操作方法)
1.线性表
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
typedef struct{
char *elem;
int length;
int listsize;
}SqList;
int InitList_Sq(SqList *L) {
// 构造一个空的线性表L。
L->elem = (char *)malloc(LIST_INIT_SIZE*sizeof(char));
if (!L->elem) return 0;
L->length = 0;
L->listsize = LIST_INIT_SIZE;
return 1;
}
int insertChar(SqList *p,int i,char a){
if(i > p->length){
printf("插入的位置不合法,插入操作失败\n");
return 0;
}
int ad;
//增加一位长度
p->length= p->length+1;
//移位
for(ad = p->length;ad>i-1;ad--){
p->elem[ad] = p->elem[ad-1];
}
//插入
p->elem[i-1] = a;
return 1;
}
int delChar(SqList *p,int i){
if(i > p->length){
printf("的位置不合法,插入操作失败\n");
return 0;
}
for(;i <= p->length;i++){
p->elem[i-1] = p->elem[i];
}
p->length--;
return 1;
}
在线性表的结构体中,主要的是指针,作用和功能与C语言中的数组差不多,只是多了length等辅助数据说明
2.链表
typedef struct LNode{
char data;
struct LNode *next;
}LNode, LinkList;
LinkList *creatList(){ //表的初始化
LinkList *head,*tail,*p;
int i=1;
char d;
head = (LinkList *)malloc(sizeof(LinkList));//创建头结点
head->next = NULL;
tail = head;
printf("初始化链表");
while(1){
printf("输入第%d个数据\n",i);
scanf("%c",&d);
if(d == '\n')
scanf("%c",&d);
p = (LinkList *)malloc(sizeof(LinkList));
p->data = d;
p->next = NULL;
tail->next = p;
tail = p;
i++;
if(i>=4)
break;
}
return (head);
}
void delElem(LinkList *L,int i){ //删除指点位置元素
int j = 0;
LinkList *m ,*n;
m = n = L;
for(;j<i-1;j++){
m = m->next;
n = m->next;
}
//printf("%c\n",m->data);
//printf("%c\n",n->data);
m->next = n->next;
}
void insElem(LinkList *L,int i,char elem){
int j = 0;
LinkList *m ,*n;
LinkList *p;
p = (LinkList *)malloc(sizeof(LinkList));
p->data = elem;
p->next = NULL;
m = n = L;
for(;j<i-1;j++){
m = m->next;
n = m->next;
}
//printf("%c\n",m->data);
//printf("%c\n",n->data);
m->next = p;
p->next = n;
}
void pList(LinkList *L){ //输出链表
LinkList *tai;
tai = L;
//printf("执行");
while(1){
if(tai->next == NULL)
break;
tai = tai->next;
printf("%c\n",tai->data);
}
}
貌似这个结构体和操作函数,还是有点问题。数据结构中少了链表的长度,还有就是,删除链表中的指定位置的函数不能删除头部的数据。
3.栈
typedef struct LN{
char data;
struct LN *before;
}LNode;
class LinkList{
private:
LNode *tail;
int length;
int max_length;
public:
LinkList(int len){
this->tail = (LNode *)malloc(sizeof(LNode));
this->tail->data = NULL;
this->tail->before = NULL;
this->length = 0;
this->max_length = len;
cout<<"创建栈,初始化成功"<<endl;
}
void pushElem(LNode *p){
p->before = this->tail;
this->tail = p;
//----------长度自增1--------
this->length++;
cout<<"输入栈中成功"<<endl;
cout<<this->tail->data<<endl;
}
char popElem(){
if(this->length > 0){
char a = this->tail->data;
this->tail = this->tail->before;
this->length--;
cout<<"读取栈成功"<<endl;
//cout<<a<<endl;
return a;
}else{
cout<<"该栈已空,数据输出失败"<<endl;
}
}
};
这里开始,自学了C++,用类封装了整个 栈的数据类型和操作,看起来清爽多了。
栈其实是在链表的基础上,加了些操作上的限制。
这里有个比较的问题还没有解决。
从方法pushElem()的参数类型可以看出,压栈的元素为一个链表单元LNode,这个对于实际操作上有很大不便性。但是要是使用传数据进该方法,在方法内部创建一个链表单元再链接到链表的尾部,又出现了一个问题。就是每次在函数内部声明的LNode指针指向的地址都是一样的,这样会试程序运行莫名中断,所以使用上述代码中的,在主函数中,申请LNode指针,组装成链表单元,再压栈。
4.队列
typedef struct LN{
char data;
struct LN *next;
}LNode;
class LinkList{
private:
LNode *top;
LNode *tail;
int length;
int max_length;
public:
LinkList(int len){
this->top = (LNode *)malloc(sizeof(LNode));
this->top->data = NULL;
this->top->next = NULL;
this->tail = this->top;
this->length = 0;
this->max_length = len;
cout<<"创建队列,初始化成功"<<endl;
}
void inLine(LNode *p){
this->tail->next = p;
this->tail = p;
this->length++;
cout<<"输入队列成功"<<endl;
cout<<this->tail->data<<endl;
}
char outLine(){
if(this->length > 0){
char a = this->top->next->data;
this->top = this->top->next;
this->length--;
cout<<"读取队列成功"<<endl;
//cout<<a<<endl;
return a;
}else{
cout<<"该队列已空,数据输出失败"<<endl;
}
}
};
队列的数据结构与栈的类似,只是前驱指针改成后进的指针,多一个头指针用于outLine()操作。
5.循环队列
typedef struct LL{
char data;
LL *next;
}typeL;
class CirQueue{
private:
typeL *head;
typeL *point;
int length;
int max_length;
public:
CirQueue(int len){
this->max_length = len;
this->length = 0;
this->head = (typeL *)malloc(sizeof(typeL));
this->point = (typeL *)malloc(sizeof(typeL));
this->head = this->point;
for(int i=0;i<len-1;i++){
typeL *p;
p = (typeL *)malloc(sizeof(typeL));
p->data = NULL;
this->point->next = p;
//cout<<p<<endl;
this->point = p;
}
this->point->next = head;
this->point = head;
}
bool inLine(char d){
if(this->length < this->max_length){
this->point->data = d;
this->point = this->point->next;
this->length++;
return true;
}else
return false;
}
char outLine(){
if(this->length == 0)
return NULL;
char d = this->head->data;
this->head = this->head->next;
this->length--;
return d;
}
};
循环队列的较 队列类的不同,就是在初始化的地方(构造函数),我在构造函数直接传入队列长度的参数len,在初始化的时候,len个typeL空间,并且两两相接,形成环状(循环的要求)。至于接下来的操作的话,没什么好说的了。