Profil von 流浪卡利姆多卡利姆多驿站FotosBlogListenMehr Extras Hilfe

流浪卡利姆多

Ort
Foto 1 von 1

卡利姆多驿站

06 Dezember

算法与数据结构_第四章栈与队列_代码及课后题(2)

==============================================
StackQueue.cpp part2
==============================================
/*
* 算法题7:设有两个栈s1和s2都采用顺序表示,并且共享一个存储区域,
* 为尽量利用空间,减少溢出的可能,现采用栈顶相对,迎面增长方式存储。
* 请写出对其中一个栈进行进栈操作push,出栈操作pop,求栈顶元素top运算的算法。
* 算法假设公用空间的大小为n,要求整个公用空间被占满(两个栈顶相碰)才发溢出信息。
*/
// 创建一个空栈
PDSeqStack createEmptyStack_dseq(int n)
{
 PDSeqStack pdstack = (PDSeqStack)malloc(sizeof(struct DSeqStack));// 分配结构DSeqStack的存储空间
 if (pdstack != NULL)
 {
  pdstack->s = (DataType *)malloc(sizeof(DataType) * n);  // 分配pastack->s的存储空间
  if (pdstack->s != NULL)
  {
   pdstack->MAXNUM = n;
   pdstack->t1 = -1;          // t1初始为-1,t2初始为n
   pdstack->t2 = n;
   return (pdstack);
  }
  else
   free(pdstack);
 }
 printf("Out of space!\n");          // 存储分配失败
 return (NULL);
}
// 判断栈是否为空
int isEmptyStack_dseq(PDSeqStack pdstack)
{
 return (pdstack->t1 == -1 && pdstack->t2 == pdstack->MAXNUM);
}
// 进栈(在栈中压入一个元素x)
void push_dseq(PDSeqStack pdstack, DataType x, string dir)
{
 if (dir == "left")
 {
  if (pdstack->t1 >= pdstack->t2 - 1)
   printf("Overflow!\n");
  else
  {
   ++pdstack->t1;
   pdstack->s[pdstack->t1] = x;
  }
 }
 if (dir == "right")
 {
  if (pdstack->t2 <= pdstack->t1 + 1)
   printf("Overflow!\n");
  else
  {
   --pdstack->t2;
   pdstack->s[pdstack->t2] = x;
  }
 }
}
// 出栈(删除栈顶元素)
void pop_dseq(PDSeqStack pdstack, string dir)
{
 if (dir == "left")
 {
  if (pdstack->t1 == -1)
   printf("Underflow!\n");
  else
   --pdstack->t1;
 }
 if (dir == "right")
 {
  if (pdstack->t2 == pdstack->MAXNUM)
   printf("Underflow!\n");
  else
   ++pdstack->t2;
 }
}
// 取栈顶元素(当pastack所指的栈不为空时,求栈顶元素的值)
DataType top_dseq(PDSeqStack pdstack, string dir)
{
 if (dir == "left")
 {
  if (pdstack->t1 == -1)
  {
   printf("Stack is empty!\n");
   return (NULL);
  }
  else
   return (pdstack->s[pdstack->t1]);
 }
 if (dir == "right")
 {
  if (pdstack->t2 == pdstack->MAXNUM)
  {
   printf("Stack is empty!\n");
   return (NULL);
  }
  else
   return (pdstack->s[pdstack->t2]);
 }
 else
  return (NULL);
}
/*
* 算法题8:假设以循环链表表示队列,并且只有一个指针指向队尾元素结点(注意不设队头指针),
* 试编写相应的创建空队列、入队列和出队列的算法。
* 我又加了取队头元素和判断是否为空队列的算法。
* 在出队时候注意一个结点的情况。
*/
// 创建一个空队列
PCLinkQueue createEmptyQueue_clink()
{
 PCLinkQueue pclqu = (PCLinkQueue)malloc(sizeof(struct CLinkQueue));
 if (pclqu != NULL)
  pclqu->r = NULL;
 else
  printf("Out of space!\n");
 return (pclqu);
}
// 判断循环链表表示队列是否为空队
int isEmptyQueue_clink(PCLinkQueue pclqu)
{
 return (pclqu->r == NULL);
}
// 入队
void enQueue_clink(PCLinkQueue pclqu, DataType x)
{
 PNode p;
 p = (PNode)malloc(sizeof(struct Node)); // 申请新结点空间
 if (p == NULL)
  printf("Out of space!\n");   // 申请新结点失败
 else
 {
  p->info = x;      // 填写新结点信息
  if (pclqu->r == NULL)    // 插入前是空队列
   p->link = p;
  else
  {
   p->link = pclqu->r->link;  // 将新结点插入
   pclqu->r->link = p;
  }
  pclqu->r = p;      // 修改队尾指针
 }
}
// 出队
void deQueue_clink(PCLinkQueue pclqu)
{
 PNode p;
 if (pclqu->r == NULL)     // 队列已空
  printf("Empty queue!\n");
 else if (pclqu->r->link == pclqu->r) // 考虑只有一个结点的情况(注意这种情况)
 {
  p = pclqu->r;
  pclqu->r = NULL;
  free(p);
 }
 else         // 有两个以上结点的情况
 {
  p = pclqu->r->link;
  pclqu->r->link = p->link;   // 修改队头指针
  free(p);       // 释放已删除结点空间
 }
}
// 取队列头部结点的值
DataType frontQueue_clink(PCLinkQueue pclqu)
{
 if (pclqu->r == NULL)     // 队列已空
 {
  printf("Empty queue!\n");
  return (NULL);
 }
 else
  return (pclqu->r->link->info);
}
/*
* 算法题9:假设以数组sequ[m]存放循环队列的元素,
* 同时设置变量rear和quelen分别指示循环队列中队尾元素的位置和内含元素个数。
* 试给出此循环队列的队满条件,并写出相应的入队列和出队列的算法(在出队列算法中要返回队头元素)。
*/
// 创建一个空队列
PASeqQueue createEmptyQueue_aseq(int m)
{
 PASeqQueue pasqu = (PASeqQueue)malloc(sizeof(struct ASeqQueue)); // 分配结构ASeqQueue的存储空间
 if (pasqu != NULL)
 {
  pasqu->sequ = (DataType *)malloc(sizeof(DataType) * m);  // 分配pasqu->sequ的存储空间
  if (pasqu->sequ != NULL)
  {
   pasqu->MAXNUM = m;
   pasqu->rear = 0;          // rear、quelen初始为0
   pasqu->quelen = 0;
   return (pasqu);
  }
  else
   free(pasqu);
 }
 printf("Out of space!\n");          // 存储分配失败
 return (NULL);
}
// 判断队列是否为空
int isEmptyQueue_aseq(PASeqQueue pasqu)
{
 return (pasqu->quelen == 0);
}
// 入队(在队尾插入元素x)
void enQueue_aseq(PASeqQueue pasqu, DataType x)
{
 if (pasqu->quelen == pasqu->MAXNUM)
  printf("Full queue!\n");
 else
 {
  pasqu->sequ[pasqu->rear] = x;
  pasqu->rear = (pasqu->rear + 1) % pasqu->MAXNUM;
  ++ pasqu->quelen;
 }
}
// 出队(删除队列头部元素)
int deQueue_aseq(PASeqQueue pasqu)
{
 if (pasqu->quelen == 0)
 {
  printf("Empty Queue!\n");
  return (-1);
 }
 else
 {
  --pasqu->quelen;
  return (pasqu->sequ[(pasqu->rear + pasqu->MAXNUM - pasqu->quelen - 1) % pasqu->MAXNUM]);
 }
}
// 取队列的头元素
DataType frontQueue_aseq(PASeqQueue pasqu)
{
 if (pasqu->quelen == 0)
 {
  printf("Empty Queue!\n");
  return (NULL);
 }
 else
  return (pasqu->sequ[(pasqu->rear + pasqu->MAXNUM - pasqu->quelen) % pasqu->MAXNUM]);
}
// 应用题1:Fibonacci数列的递归及非递归算法。感觉非递归纯属瞎搞,没啥意思。
int fibRecur(int n)
{
 if (n == 0 || n == 1)
  return (n);
 else
  return (fibRecur(n-2) + fibRecur(n-1));
}
int fib(int n)
{
 int m = n;
 int fib[50];
 PSeqStack st = createEmptyStack_seq(n);
 while (n != 1)
  push_seq(st, n--);
 fib[0] = 0;
 fib[1] = 1;
 while (!isEmptyStack_seq(st))
 {
  fib[top_seq(st)] = fib[top_seq(st) - 2] + fib[top_seq(st) - 1];
  pop_seq(st);
 }
 return fib[m];
}
// 应用题3:Hanoi问题的递归算法,非递归没写,貌似比较麻烦。
void Hanoi(char A, char B, char C, int n)
{
 if (n == 1)
  printf("plate%d from %c to %c\n", n, A, C);
 else
 {
  Hanoi(A, C, B, n - 1);
  printf("plate%d from %c to %c\n", n, A, C);
  Hanoi(B, A, C, n - 1);
 }
}
// 应用题4:后缀表达式求值
int postExpre(string str)
{
 int j = 0;
 PLinkStack plstack = createEmptyStack_link();
 for (int i = 0; i != str.length(); ++i)
 {
  if (str[i] == ' ')      // 如果是空格,如果前一个是数字,则进栈
  {
   if (j != 0)
    push_link(plstack, j);
   j = 0;
   continue;
  }
  if ('0' <= str[i] && str[i] <= '9')  // 如果是数字
  {
   if (j != 0)
    j = j * 10 + str[i] - '0';
   else
    j = str[i] - '0';
  }
  int m = 0, n = 0;      // 以下处理是+-*/符号的情况
  if (str[i] == '+')
  {
   if (!isEmptyStack_link(plstack))
   {
    m = top_link(plstack);
    pop_link(plstack);
   }
   else
   {
    printf("Wrong expression!");
    return (-1);
   }
   if (!isEmptyStack_link(plstack))
   {
    n = top_link(plstack);
    pop_link(plstack);
   }
   else
   {
    printf("Wrong expression!");
    return (-1);
   }
   m += n;
   push_link(plstack, m);
  }
  if (str[i] == '-')
  {
   if (!isEmptyStack_link(plstack))
   {
    m = top_link(plstack);
    pop_link(plstack);
   }
   else
   {
    printf("Wrong expression!");
    return (-1);
   }
   if (!isEmptyStack_link(plstack))
   {
    n = top_link(plstack);
    pop_link(plstack);
   }
   else
   {
    printf("Wrong expression!");
    return (-1);
   }
   n -= m;
   push_link(plstack, n);
  }
  if (str[i] == '*')
  {
   if (!isEmptyStack_link(plstack))
   {
    m = top_link(plstack);
    pop_link(plstack);
   }
   else
   {
    printf("Wrong expression!");
    return (-1);
   }
   if (!isEmptyStack_link(plstack))
   {
    n = top_link(plstack);
    pop_link(plstack);
   }
   else
   {
    printf("Wrong expression!");
    return (-1);
   }
   n *= m;
   push_link(plstack, n);
  }
  if (str[i] == '/')
  {
   if (!isEmptyStack_link(plstack))
   {
    m = top_link(plstack);
    pop_link(plstack);
   }
   else
   {
    printf("Wrong expression!");
    return (-1);
   }
   if (!isEmptyStack_link(plstack))
   {
    n = top_link(plstack);
    pop_link(plstack);
   }
   else
   {
    printf("Wrong expression!");
    return (-1);
   }
   n /= m;
   push_link(plstack, n);
  }
 }
 return (top_link(plstack));
}
int main()
{
 PSeqStack pastack = createEmptyStack_seq(100); // 创建空顺序栈
 pop_seq(pastack);        // 栈顶出栈(出错)
 int x = 0;
 x = top_seq(pastack);       // 取栈顶元素(出错)
 for (int i = 0; i != 50; ++i)     // 压入50个元素进栈
  push_seq(pastack, i);
 x = top_seq(pastack);       // 取栈顶元素
 printf("%d\n", x);
 pop_seq(pastack);        // 出栈
 x = top_seq(pastack);       // 取栈顶元素
 printf("%d\n", x);
 PLinkStack plstack = createEmptyStack_link(); // 创建空链栈
 pop_link(plstack);        // 栈顶出栈(出错)
 x = top_link(plstack);       // 取栈顶元素(出错)
 for (int i = 0; i != 50; ++i)     // 压入50个元素进栈
  push_link(plstack, i);
 x = top_link(plstack);       // 取栈顶元素
 printf("%d\n", x);
 pop_link(plstack);        // 出栈
 x = top_link(plstack);       // 取栈顶元素
 printf("%d\n", x);
 PSeqQueue paqu = createEmptyQueue_seq(100);  // 创建空顺序队列
 deQueue_seq(paqu);        // 出队(出错)
 x = frontQueue_seq(paqu);      // 取队列的头元素(出错)
 for (int i = 49; i != -1; --i)     // 50个元素入队
  enQueue_seq(paqu, i);
 x = frontQueue_seq(paqu);      // 取队列的头元素
 printf("%d\n", x);
 deQueue_seq(paqu);        // 出队
 x = frontQueue_seq(paqu);      // 取队列的头元素
 printf("%d\n", x);
 PLinkQueue plqu = createEmptyQueue_link();  // 创建空链队列
 deQueue_link(plqu);        // 出队(出错)
 x = frontQueue_link(plqu);      // 取队列的头元素(出错)
 for (int i = 49; i != -1; --i)     // 50个元素入队
  enQueue_link(plqu, i);
 x = frontQueue_link(plqu);      // 取队列的头元素
 printf("%d\n", x);
 deQueue_link(plqu);        // 出队
 x = frontQueue_link(plqu);      // 取队列的头元素
 printf("%d\n", x);
 char pChar[] = {'4', '3', '5', '6', '7', '\0'}; // 初始化数组
 int pInt = charToInt(pChar, 4);     // 调用函数将整数字符串转换为int
 printf("%d\n", pInt);
 decToBinary(-83);        // 将整数的二进制数打印出来
 PLinkQueue plquS = stackToQueue(plstack);  // 由栈建一个队列,并把栈清空
 x = frontQueue_link(plquS);      // 取队列的头元素
 printf("%d\n", x);
 PLinkStack plstackQ = queueToStack(plqu);  // 由队列建一个栈,并保留队列
 x = top_link(plstackQ);       // 取栈顶元素
 printf("%d\n", x);
 PDSeqStack pdstack = createEmptyStack_dseq(100);// 创建空的双端栈
 for (int i = 0; i != 51; ++i)     // 左右各压入0到49
 {
  push_dseq(pdstack, i, "left");
  push_dseq(pdstack, i, "right");
 }
 x = top_dseq(pdstack, "left");     // 取左边栈顶元素
 printf("%d\n", x);
 x = top_dseq(pdstack, "right");     // 取右边栈顶元素
 printf("%d\n", x);
 pop_dseq(pdstack, "right");      // 右边栈出栈
 x = top_dseq(pdstack, "right");     // 取右边栈顶元素
 printf("%d\n", x);
 PCLinkQueue pclqu = createEmptyQueue_clink(); // 创建一个空循环链表队列
 deQueue_clink(pclqu);       // 出队(出错)
 enQueue_clink(pclqu, 1);      // 1入队
 x = frontQueue_clink(pclqu);     // 取队头元素
 printf("%d\n", x);
 deQueue_clink(pclqu);       // 出队
 for (int i = 0; i != 50; ++i)     // 0到49入队
  enQueue_clink(pclqu, i);
 while (!isEmptyQueue_clink(pclqu))    // 所有元素打印并出队
 {
  x = frontQueue_clink(pclqu);
  printf("%d ", x);
  deQueue_clink(pclqu);
 }
 printf("\n");
 PASeqQueue pasqu = createEmptyQueue_aseq(10); // 创建空顺序队列
 deQueue_aseq(pasqu);       // 出队(出错)
 x = frontQueue_aseq(pasqu);      // 取队列的头元素(出错)
 for (int i = 9; i != -1; --i)     // 10个元素入队
  enQueue_aseq(pasqu, i);
 x = frontQueue_aseq(pasqu);      // 取队列的头元素
 printf("%d\n", x);
 x = deQueue_aseq(pasqu);      // 出队
 printf("%d\n", x);
 x = frontQueue_aseq(pasqu);      // 取队列的头元素
 printf("%d\n", x);
 enQueue_aseq(pasqu, 10);      // 入队
 x = frontQueue_aseq(pasqu);      // 取队列的头元素
 printf("%d\n", x);
 x = fibRecur(7);        // 计算Fibonacci数列7
 printf("fibRecur(7) = %d\n", x);
 x = fib(7);          // 计算Fibonacci数列7
 printf("fib(7) = %d\n", x);
 Hanoi('A', 'B', 'C', 3);
 x = postExpre("31 5 22 - * 70 +");    // 后缀表达式求值
 printf("31 5 22 - * 70 + = %d\n", x);
 return 0;
}
==============================================

算法与数据结构_第四章栈与队列_代码及课后题

==============================================
StackQueue.h
==============================================
#include <string>
#include <iostream>
using namespace std;
typedef int DataType;
struct SeqStack       // 顺序栈类型定义
{
 int MAXNUM;       // 栈中最大元素个数
 int t;        // t < MAXNUM,指示栈顶位置,而不是元素个数
 DataType *s;
};
typedef struct SeqStack *PSeqStack;  // 顺序栈类型的指针类型
// 算法题3:创建一个空栈
PSeqStack createEmptyStack_seq(int m);
// 算法题4:判断栈是否为空
int isEmptyStack_seq(PSeqStack pastack);
// 进栈(在栈中压入一个元素x)
void push_seq(PSeqStack pastack, DataType x);
// 出栈(删除栈顶元素)
void pop_seq(PSeqStack pastack);
// 取栈顶元素(当pastack所指的栈不为空时,求栈顶元素的值)
DataType top_seq(PSeqStack pastack);
struct Node;       // 单链表结点
typedef struct Node *PNode;    // 指向结点的指针类型
struct Node        // 单链表结点定义
{
 DataType info;
 PNode link;
};
struct LinkStack      // 链接栈类型定义
{
 PNode top;       // 指向栈顶结点
};
typedef struct LinkStack *PLinkStack; // 链接栈类型的指针类型
// 创建一个空链栈
PLinkStack createEmptyStack_link(void);
// 判断单链形式栈是否为空栈
int isEmptyStack_link(PLinkStack plstack);
// 进栈(在栈中压入一个元素)
void push_link(PLinkStack plstack, DataType x);
// 出栈
void pop_link(PLinkStack plstack);
// 取栈顶元素
DataType top_link(PLinkStack plstack);
struct SeqQueue       // 顺序队列类型定义
{
 int MAXNUM;       // 队列中最大元素个数
 int f, r;
 DataType *q;
};
typedef SeqQueue *PSeqQueue;   // 顺序队列类型的指针类型
// 创建一个空队列
PSeqQueue createEmptyQueue_seq(int m);
// 判断队列是否为空
int isEmptyQueue_seq(PSeqQueue paqu);
// 入队(在队尾插入元素x)
void enQueue_seq(PSeqQueue paqu, DataType x);
// 出队(删除队列头部元素)
void deQueue_seq(PSeqQueue paqu);
// 取队列的头元素
DataType frontQueue_seq(PSeqQueue paqu);
struct LinkQueue      // 链接队列类型定义
{
 PNode f;       // 头指针
 PNode r;       // 尾指针
};
typedef struct LinkQueue *PLinkQueue; // 链接队列类型的指针类型
// 创建一个空队列
PLinkQueue createEmptyQueue_link();
// 判断链接表示队列是否为空队
int isEmptyQueue_link(PLinkQueue plqu);
// 入队
void enQueue_link(PLinkQueue plqu, DataType x);
// 出队
void deQueue_link(PLinkQueue plqu);
// 取队列头部结点的值
DataType frontQueue_link(PLinkQueue plqu);
// 算法题1:写一个递归算法把整数字符串转换为整数
int charToInt(char *pChar, int len);
// 算法题2:编写一个算法,对于输入的十进制整数,将它的二进制表示打印出来
void decToBinary(int x);
// 算法题5:写一个算法从一个栈创建一个队列,使栈顶为队列的头,栈底为队列的尾,算法的最后要求使栈成为空栈
PLinkQueue stackToQueue(PLinkStack plstack);
// 算法题6:写一个算法从一个队列创建一个栈,使队列的头为栈顶,队列的尾为栈底,算法的最后要求使队列保持不变
PLinkStack queueToStack(PLinkQueue plqu);
/*
* 算法题7:设有两个栈s1和s2都采用顺序表示,并且共享一个存储区域,
* 为尽量利用空间,减少溢出的可能,现采用栈顶相对,迎面增长方式存储。
* 请写出对其中一个栈进行进栈操作push,出栈操作pop,求栈顶元素top运算的算法。
* 算法假设公用空间的大小为n,要求整个公用空间被占满(两个栈顶相碰)才发溢出信息。
*/
struct DSeqStack      // 双端顺序栈类型定义
{
 int MAXNUM;       // 栈中最大元素个数
 int t1, t2;       // t1、t2 < MAXNUM,指示栈顶位置,而不是元素个数
 DataType *s;
};
typedef struct DSeqStack *PDSeqStack; // 双端顺序栈类型的指针类型
// 创建一个空栈
PDSeqStack createEmptyStack_dseq(int n);
// 判断栈是否为空
int isEmptyStack_dseq(PDSeqStack pdstack);
// 进栈(在栈中压入一个元素x)
void push_dseq(PDSeqStack pdstack, DataType x, string dir);
// 出栈(删除栈顶元素)
void pop_dseq(PDSeqStack pdstack, string dir);
// 取栈顶元素(当pastack所指的栈不为空时,求栈顶元素的值)
DataType top_dseq(PDSeqStack pdstack, string dir);
/*
* 算法题8:假设以循环链表表示队列,并且只有一个指针指向队尾元素结点(注意不设队头指针),
* 试编写相应的创建空队列、入队列和出队列的算法。
* 我又加了取队头元素和判断是否为空队列的算法。
* 在出队时候注意一个结点的情况。
*/
struct CLinkQueue         // 循环链表链接队列类型定义
{
 PNode r;          // 尾指针
};
typedef CLinkQueue *PCLinkQueue;     // 循环链表链接队列类型的指针类型
// 创建一个空队列
PCLinkQueue createEmptyQueue_clink();
// 判断循环链表表示队列是否为空队
int isEmptyQueue_clink(PCLinkQueue pclqu);
// 入队
void enQueue_clink(PCLinkQueue pclqu, DataType x);
// 出队
void deQueue_clink(PCLinkQueue pclqu);
// 取队列头部结点的值
DataType frontQueue_clink(PCLinkQueue pclqu);
/*
* 算法题9:假设以数组sequ[m]存放循环队列的元素,
* 同时设置变量rear和quelen分别指示循环队列中队尾元素的位置和内含元素个数。
* 试给出此循环队列的队满条件,并写出相应的入队列和出队列的算法(在出队列算法中要返回队头元素)。
*/
struct ASeqQueue
{
 int MAXNUM;       // 队列中最大元素个数
 int rear, quelen;
 DataType *sequ;
};
typedef ASeqQueue *PASeqQueue;   // 顺序队列类型的指针类型
// 创建一个空队列
PASeqQueue createEmptyQueue_aseq(int m);
// 判断队列是否为空
int isEmptyQueue_aseq(PASeqQueue pasqu);
// 入队(在队尾插入元素x)
void enQueue_aseq(PASeqQueue pasqu, DataType x);
// 出队(删除队列头部元素)
int deQueue_aseq(PASeqQueue pasqu);
// 取队列的头元素
DataType frontQueue_aseq(PASeqQueue pasqu);
// 应用题1:Fibonacci数列的递归及非递归算法。感觉非递归纯属瞎搞,没啥意思。
int fibRecur(int n);
int fib(int n);
// 应用题3:Hanoi问题的递归算法,非递归没写,貌似比较麻烦。
void Hanoi(char A, char B, char C, int n);
// 应用题4:后缀表达式求值
int postExpre(string str);
==============================================
 
==============================================
StackQueue.cpp part1
==============================================
#include "StackQueue.h"
// 算法题3:创建一个空栈
PSeqStack createEmptyStack_seq(int m)
{
 PSeqStack pastack = (PSeqStack)malloc(sizeof(struct SeqStack)); // 分配结构SeqStack的存储空间
 if (pastack != NULL)
 {
  pastack->s = (DataType *)malloc(sizeof(DataType) * m);  // 分配pastack->s的存储空间
  if (pastack->s != NULL)
  {
   pastack->MAXNUM = m;
   pastack->t = -1;          // t初始为-1
   return (pastack);
  }
  else
   free(pastack);
 }
 printf("Out of space!\n");          // 存储分配失败
 return (NULL);
}
// 算法题4:判断栈是否为空
int isEmptyStack_seq(PSeqStack pastack)
{
 if (pastack == NULL || pastack->t == -1)
  return (1);
 else
  return (0);
}
// 进栈(在栈中压入一个元素x)
void push_seq(PSeqStack pastack, DataType x)
{
 if (pastack->t >= pastack->MAXNUM - 1)
  printf("Overflow!\n");
 else
 {
  ++pastack->t;
  pastack->s[pastack->t] = x;
 }
}
// 出栈(删除栈顶元素)
void pop_seq(PSeqStack pastack)
{
 if (pastack->t == -1)
  printf("Underflow!\n");
 else
  --pastack->t;
}
// 取栈顶元素(当pastack所指的栈不为空时,求栈顶元素的值)
DataType top_seq(PSeqStack pastack)
{
 if (pastack->t == -1)
 {
  printf("Stack is empty!\n");
  return (NULL);
 }
 else
  return (pastack->s[pastack->t]);
}
// 创建一个空链栈
PLinkStack createEmptyStack_link()
{
 PLinkStack plstack;
 plstack = (PLinkStack)malloc(sizeof(struct LinkStack));
 if (plstack != NULL)
  plstack->top = NULL;
 else
  printf("Out of space!\n");     // 创建失败
 return (plstack);
}
// 判断单链形式栈是否为空栈
int isEmptyStack_link(PLinkStack plstack)
{
 return (plstack->top == NULL);
}
// 进栈(在栈中压入一个元素)
void push_link(PLinkStack plstack, DataType x)
{
 PNode p;
 p = (PNode)malloc(sizeof(struct Node));
 if (p == NULL)
  printf("Out of space!\n");
 else
 {
  p->info = x;
  p->link = plstack->top;
  plstack->top = p;
 }
}
// 出栈
void pop_link(PLinkStack plstack)
{
 PNode p;
 if (isEmptyStack_link(plstack))
  printf("Empty stack pop!\n");
 else
 {
  p = plstack->top;
  plstack->top = plstack->top->link;
  free(p);
 }
}
// 取栈顶元素
DataType top_link(PLinkStack plstack)
{
 if (plstack->top == NULL)
 {
  printf("Stack is empty!\n");
  return (NULL);
 }
 else
  return (plstack->top->info);
}
// 创建一个空队列
PSeqQueue createEmptyQueue_seq(int m)
{
 PSeqQueue paqu = (PSeqQueue)malloc(sizeof(struct SeqQueue));// 分配结构SeqQueue的存储空间
 if (paqu != NULL)
 {
  paqu->q = (DataType *)malloc(sizeof(DataType) * m);  // 分配paqu->q的存储空间
  if (paqu->q != NULL)
  {
   paqu->MAXNUM = m;
   paqu->f = 0;          // f、r初始为0
   paqu->r = 0;
   return (paqu);
  }
  else
   free(paqu);
 }
 printf("Out of space!\n");         // 存储分配失败
 return (NULL);
}
// 判断队列是否为空
int isEmptyQueue_seq(PSeqQueue paqu)
{
 return (paqu->f == paqu->r);
}
// 入队(在队尾插入元素x)
void enQueue_seq(PSeqQueue paqu, DataType x)
{
 if ((paqu->r + 1) % paqu->MAXNUM == paqu->f)
  printf("Full queue!\n");
 else
 {
  paqu->q[paqu->r] = x;
  paqu->r = (paqu->r + 1) % paqu->MAXNUM;
 }
}
// 出队(删除队列头部元素)
void deQueue_seq(PSeqQueue paqu)
{
 if (paqu->f == paqu->r)
  printf("Empty Queue!\n");
 else
  paqu->f = (paqu->f + 1) % paqu->MAXNUM;
}
// 取队列的头元素
DataType frontQueue_seq(PSeqQueue paqu)
{
 if (paqu->f == paqu->r)
 {
  printf("Empty Queue!\n");
  return (NULL);
 }
 else
  return (paqu->q[paqu->f]);
}
// 创建一个空队列
PLinkQueue createEmptyQueue_link()
{
 PLinkQueue plqu;
 plqu = (PLinkQueue)malloc(sizeof(struct LinkQueue));
 if (plqu != NULL)
 {
  plqu->f = NULL;
  plqu->r = NULL;
 }
 else
  printf("Out of space!\n");
 return (plqu);
}
// 判断链接表示队列是否为空队
int isEmptyQueue_link(PLinkQueue plqu)
{
 return (plqu->f == NULL);
}
// 入队
void enQueue_link(PLinkQueue plqu, DataType x)
{
 PNode p;
 p = (PNode)malloc(sizeof(struct Node)); // 申请新结点空间
 if (p == NULL)
  printf("Out of space!\n");   // 申请新结点失败
 else
 {
  p->info = x;      // 填写新结点信息
  p->link = NULL;
  if (plqu->f == NULL)    // 插入前是空队列
   plqu->f = p;
  else
   plqu->r->link = p;    // 将新结点插入
  plqu->r = p;      // 修改队尾指针
 }
}
// 出队
void deQueue_link(PLinkQueue plqu)
{
 PNode p;
 if (plqu->f == NULL)     // 队列已空
  printf("Empty queue!\n");
 else
 {
  p = plqu->f;
  plqu->f = p->link;     // 修改队头指针
  free(p);       // 释放已删除结点空间
 }
}
// 取队列头部结点的值
DataType frontQueue_link(PLinkQueue plqu)
{
 if (plqu->f == NULL)     // 队列已空
 {
  printf("Empty queue!\n");
  return (NULL);
 }
 else
  return (plqu->f->info);
}
// 算法题1:写一个递归算法把整数字符串转换为整数
int charToInt(char *pChar, int len)        // len为数组中最后一个元素的下标
{
 if (len == 0)            // 递归到第一个元素,直接返回数
  return (pChar[len] - '0');
 if (pChar[len] - '0' < 0 || pChar[len] - '0' > 9)   // 元素要在0与9之间
 {
  printf("Input array is not a number array.\n");
  return (-1);
 }
 return (charToInt(pChar, len-1) * 10 + pChar[len] - '0'); // 递归调用
}
// 算法题2:编写一个算法,对于输入的十进制整数,将它的二进制表示打印出来
void decToBinary(int x)
{
 PLinkStack plstack = createEmptyStack_link(); // 用栈来存储余数
 if (x < 0)
  x = -x;
 for (int i = x; i != 0; i /= 2)
  push_link(plstack, i % 2);     // 余数进栈
 while (!isEmptyStack_link(plstack))
 {
  x = top_link(plstack);      // 取栈顶元素,打印,出栈
  printf("%d", x);
  pop_link(plstack);
 }
 printf("\n");
}
// 算法题5:写一个算法从一个栈创建一个队列,使栈顶为队列的头,栈底为队列的尾,算法的最后要求使栈成为空栈
PLinkQueue stackToQueue(PLinkStack plstack)
{
 PLinkQueue plqu = createEmptyQueue_link();
 DataType i;
 while (!isEmptyStack_link(plstack))
 {
  i = top_link(plstack);
  enQueue_link(plqu, i);
  pop_link(plstack);
 }
 return (plqu);
}
// 算法题6:写一个算法从一个队列创建一个栈,使队列的头为栈顶,队列的尾为栈底,算法的最后要求使队列保持不变
PLinkStack queueToStack(PLinkQueue plqu)
{
 PLinkStack plstack = createEmptyStack_link();
 PLinkStack plstackA = createEmptyStack_link();
 PLinkQueue plquA = createEmptyQueue_link();
 DataType i;
 while (!isEmptyQueue_link(plqu))
 {
  i = frontQueue_link(plqu);     // 取队列plqu头元素i并出队
  deQueue_link(plqu);
  enQueue_link(plquA, i);      // 将i在plquA入队
  push_link(plstackA, i);      // 将i入栈plstackA
 }
 while (!isEmptyStack_link(plstackA))   // 将plstackA的元素依次出栈并入plstack栈
 {
  i = top_link(plstackA);
  pop_link(plstackA);
  push_link(plstack, i);
 }
 plqu->f = plquA->f;        // 将plqu指向plquA,以保持队列不变
 plqu->r = plquA->r;
 free(plstackA);         // 释放中间队列结构及中间栈结构所占空间
 free(plquA);
 return (plstack);
}
==============================================
02 Dezember

C语言用链表实现线性表

算法与数据结构(C语言版)张乃孝编著,那本书上的第二章链表代码及部分课后题代码,希望对学数据结构的人有帮助。

==============================================

LinkList.h

==============================================

typedef int DataType;
struct Node;     // 单链表节点类型(声明)
typedef struct Node* PNode;  // 结点指针类型
struct Node      // 单链表结点结构
{
 DataType info;
 PNode link;
};
typedef struct Node * LinkList; // 单链表类型

// 创建空链表
LinkList createNullList_link();
// 判断单链表是否为空
int isNullList_link(LinkList llist);
// 在单链表中求某元素的存储位置(在带头结点的单链表llist中,找第一个值为x的结点存储位置)
PNode locate_link(LinkList llist, DataType x);
// 单链表的插入(在带头结点的单链表llist中,p所指结点后面插入元素x)
int insertPost_link(LinkList llist, PNode p, DataType x);
// 在单链表中求p所指向结点的前驱结点
PNode locatePre_link(LinkList llist, PNode p);
// 课后习题6:单链表的插入(在带头结点的单链表llist中,p所指结点前面插入元素x)
int insertPre_link(LinkList llist, PNode p, DataType x);
// 单链表的删除(在带有头结点的单链表llist中,删除第一个值为x的结点)
int deleteV_link(LinkList llist, DataType x);
// 课后习题7:单链表的删除(在带有头结点的单链表llist中,删除结点p)
int deleteP_link(LinkList llist, PNode p);
// 课后习题8:在无头结点的单链表中,删除下标为i的结点
int deleteI_link(LinkList llist, int i);
// 课后习题9:在无头结点的单链表llist中,删除从下标为i的结点开始的连续k个结点
int deleteRegion_link(LinkList llist, int i, int k);
// 课后习题10(单链表实现部分):求出下标为i的元素的前驱和后继
int findPrePost_link(LinkList llist, int i, DataType &m, DataType &n);
// 课后习题11(单链表实现部分):找出值为x的元素的前驱和后继的存储位置(即指针)
int locatePrePost_link(LinkList llist, DataType x, PNode &p, PNode &q);
// 课后习题12:删除单链表中值相同的结点
void deleteRepeatNode(LinkList llist);
// 课后习题15:合并两个带表头的单链表
void merge_link(LinkList llistA, LinkList llistB);==============================================

 

==============================================

LinkList.cpp

==============================================

#include "LinkList.h"
#include <iostream>

using namespace std;

// 创建空链表
LinkList createNullList_link()
{
 LinkList llist = (LinkList)malloc(sizeof(struct Node)); // 申请表头结点空间
 if (llist != NULL)
  llist->link = NULL;
 else
  printf("Out of space!\n");       // 创建失败
 return (llist);
}

// 判断单链表是否为空
int isNullList_link(LinkList llist)
{
 return (llist->link == NULL);
}

// 在单链表中求某元素的存储位置(在带头结点的单链表llist中,找第一个值为x的结点存储位置)
PNode locate_link(LinkList llist, DataType x)
{
 PNode p;
 if (llist == NULL)
  return (NULL);
 p = llist->link;
 while (p->info != x && p->link != NULL)
  p = p->link;
 if (p->info == x)
  return (p);
 else
  return (NULL);
}

// 单链表的插入(在带头结点的单链表llist中,p所指结点后面插入元素x)
int insertPost_link(LinkList llist, PNode p, DataType x)
{
 PNode q = (PNode)malloc(sizeof(struct Node)); // 申请新结点
 if (q == NULL)
 {
  printf("Out of space!\n");
  return (0);
 }
 else
 {
  q->info = x;
  q->link = p->link;
  p->link = q;
 }
 return (1);
}

// 在单链表中求p所指向结点的前驱结点
PNode locatePre_link(LinkList llist, PNode p)
{
 PNode q;
 if (llist == NULL)
  return (NULL);
 q = llist;
 while (q != NULL && q->link != p)
  q = q->link;
 return (q);
}

// 课后习题6:单链表的插入(在带头结点的单链表llist中,p所指结点前面插入元素x)
int insertPre_link(LinkList llist, PNode p, DataType x)
{
 PNode q = locatePre_link(llist, p);
 if (q == NULL)
  return (0);
 int ret = insertPost_link(llist, q, x);
 if (ret == 0)
  return (0);
 else
  return (1);
}

// 单链表的删除(在带有头结点的单链表llist中,删除第一个值为x的结点)
int deleteV_link(LinkList llist, DataType x)
{
 PNode p, q;
 if (llist == NULL)
  return (0);
 p = llist;
 while (p->link != NULL && p->link->info != x)
  p = p->link;  // 找值为x的结点的前驱结点的存储位置
 if (p->link == NULL) // 没有找到值为x的结点
 {
  printf("Not exist!\n");
  return (0);
 }
 q = p->link;   // 找到值为x的结点,删除该结点
 p->link = q->link;
 q->link = NULL;   // 加的这句,将q的link置空
 free(q);
 return (1);
}

// 课后习题7:单链表的删除(在带有头结点的单链表llist中,删除结点p)
int deleteP_link(LinkList llist, PNode p)
{
 PNode q;
 if (llist == NULL)
  return (0);
 q = locatePre_link(llist, p); // 找p的前一个元素q
 if (q == NULL)     // p不存在于llist中
 {
  printf("PNode p not exist in llist!\n");
  return (0);
 }
 q->link = p->link;    // 找到q,删除p
 p->link = NULL;
 free(p);
 return (1);
}

// 课后习题8:在无头结点的单链表中,删除下标为i的结点
int deleteI_link(LinkList llist, int i)
{
 if (i < 0)
  return (0);
 PNode p = llist, q = llist;
 if (p == NULL)
  return (0);
 int j = 0;
 while (p->link != NULL && j != i + 1) // j计数,找到尾,q指示前一个元素,p指示当前元素
 {
  ++j;
  q = p;
  p = p->link;
 }
 if (j == i + 1)
 {
  q->link = p->link;
  p->link = NULL;
  free(p);
  return (1);
 }
 return (0);
}

// 课后习题9:在无头结点的单链表llist中,删除从下标为i的结点开始的连续k个结点
int deleteRegion_link(LinkList llist, int i, int k)
{
 if (i < 0)
  return (0);
 PNode p = llist, q = llist;
 if (p == NULL)
  return (0);
 int j = 0, n = 0;
 while (p->link != NULL && j != i + 1) // j计数,找到尾,q指示前一个元素,p指示当前元素
 {
  ++j;
  q = p;
  p = p->link;
 }
 if (j == i + 1)
 {
  while (p->link != NULL && n != k) // 注意指针操作
  {
   ++n;
   q->link = p->link;
   p->link = NULL;
   free(p);
   p = q->link;
  }
  return (1);
 }
 return (0);
}

// 课后习题10(单链表实现部分):求出下标为i的元素的前驱和后继
int findPrePost_link(LinkList llist, int i, DataType &m, DataType &n)
{
 if (i < 0)
 {
  printf("Element not exist!\n");
  return (0);
 }
 PNode p = llist, q = llist;
 if (p == NULL)
 {
  printf("Empty LinkList!\n");
  return (0);
 }
 int j = 0;
 while (j != i + 1 && p->link != NULL)
 {
  ++j;
  q = p;
  p = p->link;
 }
 if (j != i + 1)
 {
  printf("Element not exist!\n");
  return (0);
 }
 else   // 注意处理当结点是第一结点或最后一个结点的情况
 {
  if (q == llist)
   m = NULL;
  else
   m = q->info;
  if (p->link == NULL)
   n = NULL;
  else
   n = p->link->info;
  return (1);
 }
}

// 课后习题11(单链表实现部分):找出值为x的元素的前驱和后继的存储位置(即指针)
int locatePrePost_link(LinkList llist, DataType x, PNode &p, PNode &q)
{
 p = llist, q = llist;
 if (q == NULL)
  return (0);
 while (q->info != x && q->link != NULL)
 {
  p = q;
  q = q->link;
 }
 if (q->link == NULL && q->info != x)  // 注意区分几种情况,链表中没有x值
 {
  q = NULL;
  p = NULL;
  return (0);
 }
 else if (q->link == NULL && q->info == x) // x是单链表最后一个元素
 {
  if (p == llist)
   p = NULL;
  q = NULL;
  return (1);
 }
 else          // x是单链表中间一个元素
 {
  if (p == llist)
   p = NULL;
  q = q->link;
  return (1);
 }
}

// 课后习题12:删除单链表中值相同的结点
void deleteRepeatNode(LinkList llist)
{
 PNode p = llist->link, q = p, t = p;
 DataType x;
 if (p == NULL)
  return;
 while (p->link != NULL)       // 外层循环控制p从第一个结点到最后一个结点
 {
  x = p->info;
  for (q = p; q->link != NULL;)    // 中层循环控制q、t(p的下一个结点)从p到最后一个结点循环,以判断是否为x
  {
   t = q->link;
   while (t->info == x && q->link != NULL) // while循环为了处理多个x值相邻的情况
   {
    if (t->link == NULL)
    {
     q->link = NULL;
     free(t);
    }
    else
    {
     q->link = t->link;
     free(t);
    }
   }
   if (q->link != NULL)     // 就这个语句因为开始放在for循环里,没判断,让我看了接近一个小时
    q = q->link;
  }
  p = p->link;
 }
}

// 课后习题15:合并两个带表头的单链表
void merge_link(LinkList llistA, LinkList llistB)
{
 PNode p = llistA->link, q = llistB, r = q;
 while (p->link != NULL && q->link != NULL)
 {
  r = q->link;  // 取llistB中q后面结点,插入llistA中的p后面,p后移两个元素
  q->link = r->link;
  r->link = p->link;
  p->link = r;
  p = p->link->link;
 }
 if (p->link == NULL && q->link != NULL)
 {
  p->link = q->link;
  q->link = NULL;
 }
}

int main()
{
 LinkList llist = createNullList_link();  // 创建空链表
 PNode p = llist;
 for (int i = 0; i != 20; ++i)    // 插入二十个元素到链表
 {
  int j = insertPost_link(llist, p, i);
  if (j == 0)
   printf("insertPost_link error!\n");
 }
 while (p->link != NULL)
 {
  p = p->link;
  cout << p->info << " ";
 }
 cout << endl;
 p = locate_link(llist, 5);     // 将p定位到元素值为5的结点上
 if (p == NULL)
  printf("locate_link error!\n");
 cout << p->info << endl;
 int ret = insertPre_link(llist, p, 6);  // 在结点p前插入6
 if (ret == 0)
  printf("insertPre_link error!\n");
 ret = deleteV_link(llist, 8);    // 删除值为8的结点
 if (ret == 0)
  printf("deleteV_link error!\n");
 p = locate_link(llist, 5);     // 将p定位到元素值为5的结点上
 if (p == NULL)
  printf("locate_link error!\n");
 ret = deleteP_link(llist, p);    // 将结点p删除
 if (ret == 0)
  printf("deleteP_link error!\n");
 ret = deleteI_link(llist, 5);    // 删除下标为5的元素
 if (ret == 0)
  printf("deleteI_link error!\n");
 ret = deleteRegion_link(llist, 5, 4);  // 从下标5的元素开始删除4个元素
 if (ret == 0)
  printf("deleteRegion_link error!\n");
 DataType m, n;
 ret = findPrePost_link(llist, 5, m, n);  // 找出下标为5的元素的前驱和后继
 if (ret == 0)
  printf("locatePrePost_link error!\n");
 printf("m = % d\n", m);
 printf("n = % d\n", n);
 PNode x, y;
 ret = locatePrePost_link(llist, 18, x, y); // 找出值为18的元素的前驱和后继位置(即指针)
 if (ret == 0)
  printf("locatePrePost_link error!\n");
 if (x != NULL)
  printf("x->info = % d\n", x->info);
 else
  printf("x = NULL\n");
 if (y != NULL)
  printf("y->info = % d\n", y->info);
 else
  printf("y = NULL\n");
 p = llist;         // 输出单链表中的值
 while (p->link != NULL)
 {
  p = p->link;
  cout << p->info << " ";
 }
 cout << endl;
 p = locate_link(llist, 6);     // p定位于值为6的元素上
 if (p == NULL)
  printf("locate_link error!\n");
 ret = insertPost_link(llist, p, 3);   // p之后插入3
 if (ret == 0)
  printf("insertPost_link error!\n");
 ret = insertPost_link(llist, p, 2);   // p之后插入2
 if (ret == 0)
  printf("insertPost_link error!\n");
 ret = insertPost_link(llist, p, 1);   // p之后插入1
 if (ret == 0)
  printf("insertPost_link error!\n");
 ret = insertPost_link(llist, p, 0);   // p之后插入0
 if (ret == 0)
  printf("insertPost_link error!\n");
 p = llist;         // 输出单链表中的值
 while (p->link != NULL)
 {
  p = p->link;
  cout << p->info << " ";
 }
 cout << endl;
 deleteRepeatNode(llist);     // 删除单链表中重复元素
 p = llist;         // 输出单链表中的值
 while (p->link != NULL)
 {
  p = p->link;
  cout << p->info << " ";
 }
 cout << endl;
 LinkList llistB = createNullList_link(); // 创建空链表
 p = llistB;
 for (int i = 0; i != 20; ++i)    // 插入二十个元素到链表
 {
  int j = insertPost_link(llist, p, i);
  if (j == 0)
   printf("insertPost_link error!\n");
 }
 merge_link(llist, llistB);     // 合并llist与llistB
 p = llist;         // 输出单链表中的值
 while (p->link != NULL)
 {
  p = p->link;
  cout << p->info << " ";
 }
 cout << endl;
 return 0;
}==============================================

C语言用顺序表实现线性表

    上完Internet课了,脑子里又灌了好多东西。听晕了。李老师鼓励大家放点代码网上,我也把自己当练习的内容发上来,是一本数据结构上的线性表的代码及部分课后题代码~

    后面好多习题主要是调试比较麻烦,很多题写了一个小时。大部分函数都经过了边界上的值和特殊值测试。希望对需要的人有点用。

    以后写完了后面的也会发上来玩~

 

 

==============================================

SeqList.h

==============================================

typedef int DataType;

struct SeqList
{
 int MAXNUM;   // 顺序表中最大元素的个数
 int n;    // 存放线性表中元素的个数n <= MAXNUM
 DataType* element; // element[0], element[1], ..., element[n - 1]存放线性表中的元素
};

typedef struct SeqList *PSeqList;

// 创建空顺序表
PSeqList createNullList_seq(int m);
// 判断线性表是否为空
int isNullList_seq(PSeqList palist);
// 在顺序表中求某元素的下标
int locate_seq(PSeqList palist, DataType x);
// 顺序表的插入(元素p之前插入)
// 我做了一点改进,将空表插入和非空表插入统一
int insertPre_seq(PSeqList palist, int p, DataType x);
// 课后习题1:顺序表的插入(元素p之后插入)
int insertPost_seq(PSeqList palist, int p, DataType x);
// 顺序表的删除(根据下标删除)
int deleteP_seq(PSeqList palist, int p);
// 课后习题2:顺序表的删除(根据元素值删除)
int deleteV_seq(PSeqList palist, DataType x);
// 课后习题3:将顺序表表示的线性表逆置
int swap_seq(PSeqList palist);
// 课后习题4:找出最小的元素,并返回其下标
int locateSmall_seq(PSeqList palist);
/*
* 课后习题5:删除线性表中所有值为x的值
* 我给出的算法,在一个线性表中实现,设置了2个游标
*/
int deleteAllV_seq(PSeqList palist, DataType x);
// 课后习题10(顺序表实现部分):求出下标为i的元素的前驱和后继
int findPrePost_seq(PSeqList palist, int i, DataType &m, DataType &n);
// 课后习题11(顺序表实现部分):找出值为x的元素的前驱和后继的存储位置(即下标)
int locatePrePost_seq(PSeqList palist, DataType x, int &i, int &j);

==============================================

 

==============================================

SeqList.cpp

==============================================

#include "SeqList.h"
#include <iostream>
using namespace std;

// 创建空顺序表
PSeqList createNullList_seq(int m)
{
 PSeqList palist = (PSeqList)malloc(sizeof(struct SeqList));
 if (palist != NULL)
 {
  palist->element = (DataType*)malloc(sizeof(DataType) * m);
  if (palist->element)
  {
   palist->MAXNUM = m;
   palist->n = 0;  // 空表长度为0
   return (palist);
  }
  else
   free(palist);
 }
 printf("Out of space!\n"); // 存储分配失败
 return NULL;
}

// 判断线性表是否为空
int isNullList_seq(PSeqList palist)
{
 return (palist->n ==0);
}

// 在顺序表中求某元素的下标
int locate_seq(PSeqList palist, DataType x)
{
 int q;
 for (q = 0; q < palist->n; ++q)
  if (palist->element[q] == x)
   return (q);
 return (-1);
}

// 顺序表的插入(元素p之前插入)
// 我做了一点改进,将空表插入和非空表插入统一
int insertPre_seq(PSeqList palist, int p, DataType x)
{
 ++palist->n;
 if (palist->n > palist->MAXNUM)      // 溢出
 {
  --palist->n;
  printf("Overflow!\n");
  return (0);
 }
 if (p < 0 || p >= palist->n)      // 不存在下标为p的元素
 {
  --palist->n;
  printf("Not exist!\n");
  return (0);
 }
 int q;
 for (q = palist->n - 1; q != p; --q)
  palist->element[q] = palist->element[q - 1]; // 插入位置及之后的元素均后移一个位置
 palist->element[q] = x;        // 插入元素x
 return (1);
}

// 课后习题1:顺序表的插入(元素p之后插入)
int insertPost_seq(PSeqList palist, int p, DataType x)
{
 if (p < 0 || p >= palist->n)
 {
  printf("Not exist!\n");
  return (0);
 }
 ++palist->n;
 if (palist->n >= palist->MAXNUM)
 {
  --palist->n;
  printf("Overflow!\n");
  return (0);
 }
 int q;
 for (q = palist->n - 1; q != p + 1; --q)
  palist->element[q] = palist->element[q - 1];
 palist->element[q] = x;
 return (1);
}

// 顺序表的删除(根据下标删除)
int deleteP_seq(PSeqList palist, int p)
{
 if (p < 0 || p >= palist->n)      // 不存在下标为p的元素
 {
  printf("Not exist!\n");
  return (0);
 }
 int q;
 for (q = p; q < palist->n - 1; ++q)
  palist->element[q] = palist->element[q + 1]; // 被删除元素之后的元素均前移一个位置
 palist->element[palist->n - 1] = 0;     // 自己加的这句,把后面一个元素置0
 --palist->n;          // 元素个数减1
 return (1);
}

// 课后习题2:顺序表的删除(根据元素值删除)
int deleteV_seq(PSeqList palist, DataType x)
{
 int p = locate_seq(palist, x);
 if (p == -1)
 {
  printf("Not exist!\n");
  return (0);
 }
 deleteP_seq(palist, p);
 return (1);
}

void josephus_seq(PSeqList palist, int s, int m)
{
 int s1, i, w;
 s1 = s - 1;
 for (i = palist->n; i > 0; --i)
 {
  s1 = (s1 + m -1) % i;
  w = palist->element[s1];
  printf("Out element % d \n", w);
  deleteP_seq(palist, s1);
 }
}

// 课后习题3:将顺序表表示的线性表逆置
int swap_seq(PSeqList palist)
{
 if (palist->n < 0 || palist->n > palist->MAXNUM)
  return (0);
 DataType tempEle;
 for (int i = 0; i != palist->n / 2; ++i)
 {
  tempEle = palist->element[i];
  palist->element[i] = palist->element[palist->n - 1 - i];
  palist->element[palist->n - 1 - i] = tempEle;
 }
 return (1);
}

// 课后习题4:找出最小的元素,并返回其下标
int locateSmall_seq(PSeqList palist)
{
 if (palist->n == 0)
 {
  printf("Empty SeqList!\n");
  return (-1);
 }
 DataType tempEle = palist->element[0];
 int p, q = 0;
 for (p = 0; p != palist->n; ++p)
  if (palist->element[p] < tempEle)
  {
   q = p;
   tempEle = palist->element[p];
  }
 return (q);
}

/*
* 课后习题5:删除线性表中所有值为x的值
* 用张婷的算法实现,即新建一个线性表,
* 然后通过比较原线性表中每个元素与x的值决定是否拷贝到新线性表
* 这个和下面那个函数写了接近1个小时07.11.18 22:20-23:15
*/
/*
int deleteAllV_seq(PSeqList palist, DataType x)
{
 if (palist->n == 0)
 {
  printf("Empty SeqList!\n");
  return (0);
 }
 PSeqList temppalist = createNullList_seq(palist->n);
 temppalist->n = palist->n;
 int j = 0;
 for (int i = 0; i != palist->n; ++i)
 {
  while (palist->element[i] == x && i != palist->n - 1)
   ++i;
  if (i != palist->n - 1)
  {
   temppalist->element[j] = palist->element[i];
   ++j;
  }
 }
 if (palist->element[palist->n - 1] != x)
 {
  temppalist->element[j] = palist->element[palist->n - 1];
  ++j;
 }
 temppalist->n = j;
 for (int i = 0; i != temppalist->n; ++i)
  palist->element[i] = temppalist->element[i];
 palist->n = temppalist->n;
 free(temppalist->element);
 free(temppalist);
 return (1);
}
*/

/*
* 课后习题5:删除线性表中所有值为x的值
* 我给出的算法,在一个线性表中实现,设置了2个游标
*/
int deleteAllV_seq(PSeqList palist, DataType x)
{
 if (palist->n == 0)
 {
  printf("Empty SeqList!\n");
  return (0);
 }
 int p = 0, q = 0;
 while (palist->element[p] != x && p != palist->n - 1)  // 跳过开始不是x的元素
 {
  ++p;
  ++q;
 }
 for (; p != palist->n - 1; ++p)        // 遍历元素,不遍历最后一个元素(为了防止越界)
 {
  while (palist->element[p] == x && p != palist->n - 1) // 如果元素是x,则游标p后移(用while处理多个x连续的情况)
  {
   ++p;
  }
  if (p != palist->n - 1)
  {
   palist->element[q] = palist->element[p];
   ++q;
  }
 }
 if (palist->element[palist->n - 1] != x)
 {
  palist->element[q] = palist->element[palist->n - 1];
  ++q;
 }
 palist->n = q;
 return (1);
}

// 课后习题10(顺序表实现部分):求出下标为i的元素的前驱和后继
int findPrePost_seq(PSeqList palist, int i, DataType &m, DataType &n)
{
 if (i < 0 || i >= palist->n)
 {
  printf("Element %d not exist!\n", i);
  return (0);
 }
 if (i == 0)
 {
  printf("No pre element!\n");
  m = NULL;
 }
 else
  m = palist->element[i - 1];
 if (i == palist->n - 1)
 {
  printf("No post element!\n");
  n = NULL;
 }
 else
  n = palist->element[i + 1];
 return (1);
}

// 课后习题11(顺序表实现部分):找出值为x的元素的前驱和后继的存储位置(即下标)
int locatePrePost_seq(PSeqList palist, DataType x, int &i, int &j)
{
 int k = locate_seq(palist, x);
 if (k == -1)
  return (0);
 if (k == 0)
  i = -1;
 else
  i = k - 1;
 if (k == palist->n - 1)
  j = -1;
 else
  j = k + 1;
 return (1);
}

int main()
{
 PSeqList palist = createNullList_seq(100);
 for (int i = 0; i < 50; ++i)
 {
  ++palist->n;
  palist->element[i] = i;
 }
 int ret;
 ret = insertPre_seq(palist, 10, 30); // 在下标为10的元素之前插入30
 if (ret == 0)
  printf("insertPre_seq error!\n");
 ret = insertPre_seq(palist, 30, 30); // 在下标为30的元素之前插入30
 if (ret == 0)
  printf("insertPre_seq error!\n");
 ret = insertPre_seq(palist, 48, 30); // 在下标为48的元素之前插入30
 if (ret == 0)
  printf("insertPre_seq error!\n");
 ret = insertPost_seq(palist, 52, 30); // 在下标为52的元素之后插入30
 if (ret == 0)
  printf("insertPost_seq error!\n");
 ret = insertPost_seq(palist, 30, 30); // 在下标为30的元素之后插入30
 if (ret == 0)
  printf("insertPost_seq error!\n");
 ret = deleteP_seq(palist, 35);   // 删除下标为35的元素
 if (ret == 0)
  printf("deleteP_seq error!\n");
 ret = deleteV_seq(palist, 36);   // 删除值为36的元素
 if (ret == 0)
  printf("deleteV_seq error!\n");
 for (int i = 0; i < palist->n; ++i)  // 输出线性表的元素值
  cout << palist->element[i] << " ";
 cout << endl;
 ret = deleteAllV_seq(palist, 30);  // 删除所有值为30的元素
 if (ret == 0)
  printf("deleteAllV_seq error!\n");
 for (int i = 0; i < palist->n; ++i)  // 输出线性表的元素值
  cout << palist->element[i] << " ";
 cout << endl;
 DataType j, k;
 ret = findPrePost_seq(palist, 30, j, k);// 找出下标为30的元素的前驱和后继
 if (ret == 0)
  printf("findPrePost_seq error!\n");
 else
 {
  printf("j = % d\n", j);
  printf("k = % d\n", k);
 }
 int x, y;
 ret = locatePrePost_seq(palist, 31, x, y);// 找出值为31的元素的前驱和后继的下标
 if (ret == 0)
  printf("locatePrePost_seq error!\n");
 else
 {
  if (x == -1)
   printf("No pre element!\n");
  else
   printf("Pre element[%d] = %d\n", x, palist->element[x]);
  if (y == -1)
   printf("No post element!\n");
  else
   printf("Post element[%d] = %d\n", y, palist->element[y]);
 }

 PSeqList jos_alist;
 int i;
 int n, s, m;
 printf("\n please input the values( < 100) of n = ");
 cin >> n;
 printf("please input the values of s = ");
 cin >> s;
 printf("please input the values of m = ");
 cin >> m;
 jos_alist = createNullList_seq(n);
 if (jos_alist != NULL)
 {
  for (int i = 0; i < n; ++i)
   insertPre_seq(jos_alist, i, i + 1);
  josephus_seq(jos_alist, s, m);
  free(jos_alist->element);
  free(jos_alist);
 }
 return 0;
}

==============================================

01 September

明天报到

     明天北大研究生报到。想想,我已经在家呆了一年的时间了。这一年,有奋斗,也有彷徨。忘不了和宝宝、战群、驴一起在聊大自习的情景。也记得和哥们一起在时空、万科疯狂RPG、dota的点滴。突然又一次离开家,心里百感交集。有对新生活的期待,有对研究生生活的压力,还有离开家心里说不出来的一种特殊感受。不过还是妈说得对,这么大个人了,老在家呆着也不是个事。鸟儿长大了,翅膀硬了,就得飞向广阔的天空。
     明天独自一个人去北京,这个对我不算陌生的城市。其实这次是自己要求独自去北京的,一来北京已经去过5次了,二来想表明自己的确长大了,可以自己出去闯。
     虽然研究生对我来说还是个未知数,但是自己知道自己应该走的路,和自己应该坚守的原则。
     08年北京奥运会口号是“新北京,新奥运”,咱也来一句,“新北京,新生活~”!马大加油~
     兄弟姐妹们咱们北京见!
13 August

终于收到录取通知书了

      下午回到家,知道通知书到了。开学真早,9月2号报到。
      马上就要进入一个全新的环境,现在想起来刚上大学那会,那时候第一次离开家一个人生活,非常不习惯。到了北京,得好好把握自己,清楚什么对于我是最重要的。因为以后的这两年是我人生中至关重要的两年。
      我的心不再流浪,我要在那个陌生的城市里找到自己真正需要的。学业上的,感情上的。
      不再沉迷游戏。超越自己。一艘小船只有驶离了阴暗的角落,才能投入大海的怀抱。北京将会是我实现梦想的地方~马大,FIGHTING!
31 Juli

戒游戏了~

     7月22日,把家里电脑上的游戏全部删除。决定:从此以后在个人的电脑上不玩游戏~只有和同学出去玩的时候可以陪大家玩一会! 找回自我~
28 Juli

一生中最值得珍惜的十个人(转)

      遇到真爱的有时,要努力争取和他相伴一生的机会, 因为当他离开时,一切都来不及了.

 遇到可以相信的朋友时,要好好和他相处下去, 因为有一生中,遇到知己真的不易.

 遇到贵人时,记得好好感激,因为他是你人生的转折点.

 遇到曾经爱过的人时,要记得感激他,因为他让你更懂得爱. 

 遇到曾经恨过的人时,要微笑向他打招呼,因为他让你更加坚强.

 遇到曾经背叛你的人时,要好好和他聊一聊,因为若不是他,今天我不看懂这个世界.

 遇到曾经暗恋的人时,要祝他幸福,因为你喜欢他时,不就是希望他幸福吗?

 遇到匆匆离开的人时,要谢谢他走过你的人生, 因为他是你精彩回忆的一部分.

 遇到曾经和你有误会的人时,要解清误会,因为你可能只有这一次机会解释清楚.

 遇到和你相伴一生的人时,要百分百地感谢他爱你, 因为你们现在都得到了幸福和真爱. 

17 Juli

在家乡迷路

     说来搞笑,时隔10多年,又一次在家乡迷路了。
     下了从济南到聊城的汽车,突然发现自己不知道自己在什么位置。车没有进汽车站,而周围的街和建筑我一点都不熟悉。天有些晚,我看不清楚远处的建筑。我让妹妹辨别一下,前面是汽车站么,她好像也没看清楚,就说是。向前走了好远,过了3、4个路口,发现不对,不可能还没到车站。静下心来,环视周围,又问了问路边的老大妈,才知道是在车站去香江的路上。于是掉头走,好远才到个站牌。
     说来惭愧,这次不仅转向,而且都不知道自己在什么位置。那种感觉好迷茫。看来以后有时间了得拉几个人出去轧马路去,熟悉熟悉家乡咯~

我心飞翔

     乘bus飞驰在济聊高速上,窗外大树飞快地向后奔跑。我倚在座位上,眼睛遥望远方。从略微打开的车窗离,透进来一阵阵树的独特气息,我闭上双眼,静静感受这生命的活力。
     那一刻,心似乎一下子松弛了下来,我的思绪也随着风飞到远方。有一种非常自由的感觉,久违了的自由的感觉!心中太多太多的感受,此刻全部突破了自我的限制,飞向辽阔的天空!
     自己的灵魂仿佛离开了自己的身体,在天地间舞蹈。在我注视的天空里,一个倔强的舞者正聚集天地的灵气,相信他马上就要翱翔!
     听过一句话:掌握自己命运的人就是神。默默对自己说:我要超越神!
15 Juni

烦躁

     昨天充满焦虑地等了一天,在第六次考试中终于把可恶的科目三考过了!真怒了!一天哪,从早晨5点半到下午四点半就吃了个面包,最后踩离合都快踩不住了,而且又有点感冒,真fuck!折磨死我了!
     今天早晨噩耗传来:舅舅没了!我真超晕!只是希望舅妈和两个孩子能够撑下去,不要太悲伤!
     下午超级烦躁,么都不想干,真不知道吃错了什么药!而且还感冒着,脑袋也不怎么清醒,跑卡丁车也不愿意跑,不知道我是怎么了啊!
01 Juni

男人最爱的女人只有一个(转载)

   人们长说痴男怨女,古人已经解释的很清楚了,痴男,男人对爱的痴情,对感情的专一也只有男人自己才知道。女人一辈子可爱上多个男人,而男人却可以同时爱上多个女人,可女人却不知道其实男人一辈子只爱过一个!

  男人真正纯洁的爱只有一次的,当那次爱来了,他会不顾一切,当那次爱死了,也就不会再有了,那次爱的太深,然而痛的也太深。

  所以那次之后男人的爱也就麻木了.男人以后也会爱上别的女孩,只是那种爱却已不再纯洁,包含了欲望,包含了同情,包含了怜惜~~~~~

  女人的心都是水做的,然而最毒也妇人心,所以受伤最多的是女人,伤人最深的也是女人。女人的爱可以有很多次,而男人却永远只有一次的,男人遇到那个最爱的女孩之后把所有的爱都给了她,可有多少女孩懂的珍惜。

  于是男人哭了,男人流泪了,伤心至极而绝望的泪水,慢慢的男人开始亲手去埋葬自己那唯一的爱,把它尘封在自己心底最深处的某个深渊。

  可当夜深人静的时候,他会疯狂的跳进那个深渊,妄图去寻找那次爱的痕迹,哪怕是一丝丝一点点,可结果却跟以往一样的一无所获,只留下自己独自缩在黑暗的角落孤独的一根根抽着寂寞的烟,孤独的流着伤心的泪水。

  当然女人埋怨着男人的花心的时候是否曾想过,男人最珍贵的东西也正是被你们无情的毁灭,当男人羞涩的说着我爱你的时候你珍惜了吗?当男人为你流泪的时候你帮他擦拭了吗?当男人乞求你别离开的时候你回头了吗?

  都说男人花心,可女人何曾知道,男人的花心是因为痴心,爱极而痴,痴极而痛,痛极而死.这次爱灰飞烟灭后男人对爱的心就死了,男人再也不会对女人真心的付出真正的好了,没有了心劲,没有了激情,不再相信真正的爱情,对爱总带着点玩世不恭,有些事,一辈子只有一次。

  当男人全心爱过一个人之后,该付出的付出了,全心努力的去把握过,曾试图给她想要的一切,曾试图为她而死,但回报却是无动于衷,于是在一次次寂寞的等待中,心血一点一滴的滴干了,最后心血全无,心灰意冷,当爱情失去信仰,当感情失去忠一的港湾后,对于男人来说,爱情是什么这一切就都显的无所谓了!男人的心冷了,就再也难以热起来,因为爱过一次之后已经让他失去了爱的能力。

  男人最爱的真的只有一个,男人心里最清楚,如果你是你能感觉到的吗,感觉到了,请你珍惜好吗?

25 Mai

人生第三次遭遇刺猬

     晚上和爸、妈在操场散步,快回家的时候,大约8:15,妈说地上有个东西在跑,老爸说是老鼠或者刺猬,老妈则说是刺猬。我很好奇,毕竟好多年没的机会一睹刺猬风采了。那个小家伙在操场里快速由南向北跑,比人走路的速度稍微慢一点。我就快速追上去,到它面前,它停住了,嘴贴着地面,一动也不动。爸妈赶上来,说它一定是吓坏了。
     我走近才看清楚,果真是一只小刺猬。棕褐色的毛,颜色淡一些的脸部,还有一个看起来蛮机灵的眼睛。看它的眼神,有一点恐慌。我想给它拍照,让爸妈都把手机拿过来照亮,但是光线还是太暗,可惜了,没拍到它。然后我们走开,它估计继续觅食去了。
     平生这是第三次碰到刺猬。第一次是在东边那个屋子住的时候,我们家南边的偏房里住了一窝刺猬,而且还产了一窝小刺猬,见过,非常可爱。第二次是和妈在捉蝉的时候,看到一只刺猬在捉蝉。第二次见刺猬距离现在有15年以上了。
     刺猬是一种性格非常孤僻的动物,喜安静,怕光、怕热、怕惊。但愿我们没有惊到这只可爱的刺猬。
23 Mai

《论语》摘抄

     读于丹《〈论语〉心得》,颇有些体会,但感觉还是原文更有意蕴。将一些自认为有用的语句摘抄下来自勉。
《论语·学而》
曾子曰:“吾日三省吾身:为人谋而不忠乎?与朋友交而不信乎?传不习乎?”
子曰:“弟子入则孝,出则悌(ti),谨而信,泛爱众,而亲仁。行有余力,则以学文。”
子曰:“君子食无求饱,居无思安,敏于事而慎于言,就有道而正焉,可谓好学也已。”
子曰:“不患人之不己知,患不知人也。”
《论语·为政》
子曰:“吾十有五而志于学,三十而立,四十而不惑,五十而知天命,六十而耳顺,七十耳从心所欲,不逾矩。”
子曰:“君子不器。”
子贡问君子。子曰:“先行其言而后从之。”
子曰:“君子周而不比,小人比而不周。”
子曰:“由,诲女知之乎?知之为知之,不知为不知,是知也。”
子曰:“人而无信,不知其可也。”
《论语·八佾(yi)》
子曰:“人而不仁,如礼何?人而不仁,如乐何?”
《论语·里仁》
子曰:“不仁者,不可以久处约,不可以长处乐。仁者安仁,知者利仁。”
子曰:“唯仁者能好人,能恶人。”
子曰:“朝闻道,夕可死也。”
子曰:“君子怀德,小人怀土;君子怀刑,小人怀惠。”
子曰:“君子喻于义,小人喻于利。”
子曰:“见贤思齐焉,见不贤而内自省也。”
子曰:“君子欲讷于言,而敏于行。”
子曰:“德不孤,必有邻。”
《论语·公冶长》
季文子三思而后行。子闻之,曰:“再,斯可矣。”
《论语·雍也》
子谓子夏曰:“女为君子儒,无为小人儒。”
子曰:“质胜文则野,文胜质则史。文质彬彬,然后君子。”
子曰:“知之者不如好之者,好之者不如乐之者。”
子曰:“知者乐水,仁者乐山;知者动,仁者静;知者乐,仁者寿。”
《论语·述而》
子曰:“德之不修,学之不讲,闻义不能徒,不善不能改,是吾忧也。”
子曰:“志于道,据于德,依于仁,游于艺。”
子曰:“三人行必有我师焉。择其善者而从之,其不善者而改之。”
子曰:“仁远乎哉?我欲仁,斯仁至矣。”
子曰:“君子坦荡荡,小人长戚戚。”
《论语·泰伯》
曾子曰:“以能问于不能,以多问于寡;有若无,实若虚,犯而不校,昔者吾友尝从事于斯矣。”
《论语·子罕》
子曰:“吾未见好德如好色者也。”
子曰:“三军可夺帅也,匹夫不可夺志也。”
子曰:“知者不惑,仁者不忧,勇者不惧。”
《论语·乡党》
食不语,寝不言。
《论语·颜渊》
司马牛问君子。子曰:“君子不忧不惧。”曰:“不忧不惧,斯谓之君子已乎?”子曰:“内省不疚,夫何忧何惧?”
子曰:“君子成人之美,不成人之恶,小人反是。”
子贡问友。子曰:“忠告而善道之,不可则之,毋自辱焉。”
曾子曰:“君子以文会友,以友辅仁。”
《论语·子路》
子曰:“其身正,不令而行;其身不正,虽令不从。”
子曰:“君子和而不同,小人同而不和。”
子曰:“君子泰而不骄,小人骄而不泰。”
《论语·宪问》
子曰:“有德者必有言,有言者不必有德;仁者必有勇,勇者不必有仁。”
《论语·卫灵公》
子曰:“志士仁人,无求生以害仁,有杀身以成仁。”
子曰:“人无远虑,必有近忧。”
子曰:“君子求诸己,小人求诸人。”
子曰:“君子矜而不争,群而不党。”
子贡问曰:“有一言而可以终身行之者乎?”子曰:“斯恕乎!己所不欲,勿施于人。”
子曰:“众恶之,必察焉;众好之,必察焉。”
子曰:“道不同,不相为谋。”
《论语·季氏》
孔子曰:“益者三友,损者三友:友直,友谅,友多闻,益矣;友便辟,友善柔,友便佞,损矣。”
孔子曰:“益者三乐,损者三乐。乐节礼乐,乐道人之善,乐多贤友,益矣;乐骄乐,乐佚游,乐宴乐,损矣。”
孔子曰:“君子有三戒:少之时,血气未定,戒之在色;及其壮也,血气方刚,戒之在斗;及其老也,血气既衰,戒之在得。”
孔子曰:“生而知之者,上也;学而知之者,次也;困而学之,又其次也。困而不学,民斯为下矣。”
《论语·阳货》
子张问仁于孔子。孔子曰:“能行五者于天下,为仁矣。”
“请问之。”曰:“恭,宽,信,敏,惠。恭则不侮,宽则得众,信则人任焉,敏则有功,惠则足以使人。”
子曰:“道听而涂说,德之弃也!”
子曰:“唯女子与小人为难养也,近之则不孙,远之则怨。”
《论语·子张》
子夏曰:“博学而笃志,切问而近思,仁在其中矣。”
子夏曰:“君子有三变:望之俨然,即之也温,听其言也厉。”
21 Mai

第一次炒菜

     受宝宝、舜舜、思思等人的启发,决心学习做饭。下决心已久,今天晚上决定行动。5点半就从来聊大自习室跑了出来,5点50到家,老妈还没回来。6点30,在老妈的指导之下开始第一次炒菜。
     菜是炒豆角,老妈已经把菜洗好了。我先把豆角分三次切成一小段一小段的,切的时候左手相当小心,生怕碰到刀。切好后,开炉子、开抽油烟机,放葵花油。然后切了一根小葱,小心翼翼地从边上放下去以防被油溅到。过了一分钟左右,把豆角放入锅中。然后就是开始翻豆角。这个过程持续很久,豆角颜色由比较白渐渐变绿,大约6点55,尝了下,基本熟了,然后放盐、鸡精、白糖一点。把菜倒入盘子就OK啦。
     看着自己做的菜,心里十分兴奋,乐呆了!让爸妈尝了下,都说相当好。自己也吃了不少,感觉还好。以后得慢慢学习做菜、烧饭,明天帮老妈包饺子哈。