广工 AnyviewC 数据结构习题 第二章

广工 AnyviewC 数据结构习题 第二章

广工 AnyviewC 数据结构习题 第二章

Anyview 数据结构 第二章

/**********

1【题目】试写一算法,实现顺序栈的判空操作

StackEmpty_Sq(SqStack S)

顺序栈的类型定义为:

typedef struct {
  ElemType *elem; // 存储空间的基址
  int top;        // 栈顶元素的下一个位置,简称栈顶位标
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack;        // 顺序栈

***********/

Status StackEmpty_Sq(SqStack S)
/* 对顺序栈S判空。                      */ 
/* 若S是空栈,则返回TRUE;否则返回FALSE */
{
    if ( S.top == 0)
        return TRUE;
     return FALSE;   
        
}

/**********

2【题目】试写一算法,实现顺序栈的取栈顶元素操作

GetTop_Sq(SqStack S, ElemType &e)

顺序栈的类型定义为:

typedef struct {
  ElemType *elem;  // 存储空间的基址
  int top;         // 栈顶元素的下一个位置,简称栈顶位标
  int size;        // 当前分配的存储容量
  int increment;   // 扩容时,增加的存储容量
} SqStack;         // 顺序栈

***********/

Status GetTop_Sq(SqStack S, ElemType &e) 
/* 取顺序栈S的栈顶元素到e,并返回OK; */ 
/* 若失败,则返回ERROR。              */
{
    if (S.top==0)
        return ERROR;
      e = S.elem[S.top-1];
      return OK;
}

/**********

3【题目】试写一算法,实现顺序栈的出栈操作

Pop_Sq(SqStack &S, ElemType &e)

顺序栈的类型定义为:

typedef struct {
  ElemType *elem;  // 存储空间的基址
  int top;         // 栈顶元素的下一个位置,简称栈顶位标
  int size;        // 当前分配的存储容量
  int increment;   // 扩容时,增加的存储容量
} SqStack;         // 顺序栈

***********/

Status Pop_Sq(SqStack &S, ElemType &e) 
/* 顺序栈S的栈顶元素出栈到e,并返回OK;*/ 
/* 若失败,则返回ERROR。               */
{
    if (S.top==0)
        return ERROR;
      e = S.elem[S.top-1];
      S.top-=1;
      return OK;
}

/**********

4 【题目】若顺序栈的类型重新定义如下。试编写算法,

构建初始容量和扩容增量分别为size和inc的空顺序栈S。

typedef struct {
  ElemType *elem; // 存储空间的基址
  ElemType *top;  // 栈顶元素的下一个位置
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack2;

***********/

Status InitStack_Sq2(SqStack2 &S, int size, int inc)
/* 构建初始容量和扩容增量分别为size和inc的空顺序栈S。*/ 
/* 若成功,则返回OK;否则返回ERROR。                 */
{
    if (size>0 && inc>0)
     {
        S.size=size;
        S.increment=inc;
        S.top=size;
        return OK;
     }        
     return ERROR;
}

/**********

5【题目】若顺序栈的类型重新定义如下。试编写算法,

实现顺序栈的判空操作。

typedef struct {
  ElemType *elem; // 存储空间的基址
  ElemType *top;  // 栈顶元素的下一个位置
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack2;

***********/

Status StackEmpty_Sq2(SqStack2 S)
/* 对顺序栈S判空。                      */ 
/* 若S是空栈,则返回TRUE;否则返回FALSE */
{
    if (S.top==S.elem)
        return TRUE;
     return FALSE;
}

/**********

6【题目】若顺序栈的类型重新定义如下。试编写算法,

实现顺序栈的入栈操作。

typedef struct {
  ElemType *elem; // 存储空间的基址
  ElemType *top;  // 栈顶元素的下一个位置
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack2;

***********/

Status Push_Sq2(SqStack2 &S, ElemType e)
/* 若顺序栈S是满的,则扩容,若失败则返回ERROR。*/
/* 将e压入S,返回OK。                          */
{
    if (S.top>=S.elem+S.size)
     {
        
        if (S.increment<=0)
            return ERROR;
        ElemType *p;
        p = (ElemType *) realloc (S.elem,(S.size+S.increment)*sizeof(ElemType));
        if (p==NULL)
            return ERROR;
        S.elem=p;
        S.top=S.elem+S.size;
        S.size+=S.increment;
        
     }
        
        *S.top=e;
        S.top++;
        return OK;
}

/**********

7 【题目】若顺序栈的类型重新定义如下。试编写算法,

实现顺序栈的出栈操作。

typedef struct {
  ElemType *elem; // 存储空间的基址
  ElemType *top;  // 栈顶元素的下一个位置
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack2;

***********/

Status Pop_Sq2(SqStack2 &S, ElemType &e) 
/* 若顺序栈S是空的,则返回ERROR;    */ 
/* 否则将S的栈顶元素出栈到e,返回OK。*/
{
    if (S.top==S.elem)
        return ERROR;    
   
    e = *(S.top-1);
    S.top-=1;
    
    return OK;
}

/**********

8【题目】试写一算法,借助辅助栈,复制顺序栈S1得到S2。

顺序栈的类型定义为:

typedef struct {
  ElemType *elem; // 存储空间的基址
  int top;        // 栈顶元素的下一个位置,简称栈顶位标
  int size;       // 当前分配的存储容量
  int increment;  // 扩容时,增加的存储容量
} SqStack;        // 顺序栈

可调用顺序栈接口中下列函数:

Status InitStack_Sq(SqStack &S, int size, int inc); // 初始化顺序栈S
Status DestroyStack_Sq(SqStack &S); // 销毁顺序栈S
Status StackEmpty_Sq(SqStack S);    // 栈S判空,若空则返回TRUE,否则FALSE
Status Push_Sq(SqStack &S, ElemType e); // 将元素e压入栈S
Status Pop_Sq(SqStack &S, ElemType &e); // 栈S的栈顶元素出栈到e

***********/

Status CopyStack_Sq(SqStack S1, SqStack &S2) 
/* 借助辅助栈,复制顺序栈S1得到S2。    */ 
/* 若复制成功,则返回TRUE;否则FALSE。 */
{
    ElemType e;
    
    SqStack S0;
   InitStack_Sq(S0, S1.size, S1.increment);
   InitStack_Sq(S2, S1.size, S1.increment);
   
   S0.top=0;
   S2.top=0;
   if (StackEmpty_Sq(S1)==TRUE )
    {            
        return TRUE;
     }   
   
   int i,l;
   l=S1.top;
   for (i=0;i<l;i++)
   {
      Pop_Sq(S1, e);
      Push_Sq(S0, e);
   }
   for (i=0;i<l;i++)
   {
      Pop_Sq(S0, e);
      Push_Sq(S2,e);
   }
   DestroyStack_Sq(S0);
   return OK;
}

/**********

9【题目】试写一算法,求循环队列的长度。

循环队列的类型定义为:

typedef struct {
  ElemType *base;  // 存储空间的基址
  int front;       // 队头位标
  int rear;        // 队尾位标,指示队尾元素的下一位置
  int maxSize;     // 最大长度
} SqQueue;

***********/

int QueueLength_Sq(SqQueue Q)
/* 返回队列Q中元素个数,即队列的长度。 */ 
{
    int l = (Q.rear - Q.front + Q.maxSize) % Q.maxSize  ;
   return l; 
}

/**********

10【题目】如果希望循环队列中的元素都能得到利用,

则可设置一个标志域tag,并以tag值为0或1来区分尾
指针和头指针值相同时的队列状态是"空"还是"满"。
试编写与此结构相应的入队列和出队列的算法。
本题的循环队列CTagQueue的类型定义如下:

typedef struct {
  ElemType elem[MAXQSIZE];
  int tag;
  int front;
  int rear;
} CTagQueue;

**********/

Status EnCQueue(CTagQueue &Q, ElemType x)
/* 将元素x加入队列Q,并返回OK;*/
/* 若失败,则返回ERROR。       */
{
    if (Q.tag == 1 && Q.front==Q.rear)
        return ERROR;
    Q.elem[Q.rear]=x;
    Q.rear=(Q.rear+1) % MAXQSIZE;
    return OK;
}

Status DeCQueue(CTagQueue &Q, ElemType &x)
/* 将队列Q的队头元素退队到x,并返回OK;*/
/* 若失败,则返回ERROR。               */
{
    if (Q.tag == 0 && Q.front==Q.rear)
        return ERROR;
    x=Q.elem[Q.front];
    Q.front=(Q.front+1) % MAXQSIZE;
    return OK;
}

/**********

11【题目】假设将循环队列定义为:以域变量rear

和length分别指示循环队列中队尾元素的位置和内
含元素的个数。试给出此循环队列的队满条件,并
写出相应的入队列和出队列的算法(在出队列的算
法中要返回队头元素)。
本题的循环队列CLenQueue的类型定义如下:

typedef struct {
  ElemType elem[MAXQSIZE];
  int length;
  int rear;
} CLenQueue;

**********/

Status EnCQueue(CLenQueue &Q, ElemType x)
  /* 将元素x加入队列Q,并返回OK;*/
  /* 若失败,则返回ERROR。       */
{
   if (Q.elem==NULL || Q.length>=MAXQSIZE)
        return ERROR;
    Q.rear = (Q.rear+1) % MAXQSIZE;
    Q.elem[Q.rear]=x;
     Q.length++;
    return OK;
}
Status DeCQueue(CLenQueue &Q, ElemType &x)
  /* 将队列Q的队头元素退队到x,并返回OK;*/
  /* 若失败,则返回ERROR。               */
{
    if (Q.elem==NULL ||Q.length==0)
        return ERROR;
    if(Q.rear+1>=Q.length)  
        x=Q.elem[Q.rear+1-Q.length];
    else
        x=Q.elem[MAXQSIZE-Q.length+Q.rear+1];
    //x = Q.elem[(Q.length-Q,rear + MAXQSIZE) % MAXQSIZE];
    --Q.length;
    return OK;
}

12【题目】已知k阶斐波那契序列的定义为:

f0=0,  f1=0,  …,  fk-2=0,  fk-1=1;
fn=fn-1+fn-2+…+fn-k,  n=k,k+1,…

试利用循环队列编写求k阶斐波那契序列中第
n+1项fn的算法。

本题的循环队列的类型定义如下:

typedef struct {
  ElemType *base; // 存储空间的基址
  int front;      // 队头位标
  int rear;       // 队尾位标,指示队尾元素的下一位置
  int maxSize;    // 最大长度
} SqQueue;
**********/
long Fib(int k, int n)
/* 求k阶斐波那契序列的第n项fn
要求:必须使用循环队列
*/
{
	long sum = 0;
	int i, j,m;
	SqQueue a;
	a.maxSize = k+1;	
	//注意循环队列由于判空判满的问题所以有一个元素空间没有用
	a.base = (ElemType*)malloc(a.maxSize * sizeof(ElemType));
	a.front = 0;
	a.rear = 0;


	if (n < k - 1)
	{
		sum = 0;
		return sum;
	}
	else if (n == k-1)
	{
		sum = 1;
		return sum;
	}

	//初始化该队列对应的斐波那契数列
	do
	{
		a.base[a.rear] = 0;

		a.rear = (a.rear + 1) % a.maxSize;
	} while ((a.rear + 1) % a.maxSize != a.front);
	a.base[a.rear-1] = 1;
	cout << a.base[a.rear-1] << endl;
	cout << a.rear << endl;
	cout << a.front << endl;
	cout << endl;

	m = a.front;
	for (i = k-1; i < n; i++)
	{
		long v = 0;
		j = a.front;
		do
		{
			v += a.base[j];
			cout << "v:" << v << "	" << "j:" << j << endl;
			j = (j + 1) % a.maxSize;
		} while ((j + 1) % a.maxSize != a.front);
		cout << endl;
		cout << "v:" << v << "	"<< "i:" << i << endl;
		cout << "rear	" << a.rear << endl;
		cout << endl;

		
		a.base[a.rear] = v;
		if ((a.rear + 1) % a.maxSize == a.front)
		{
			a.rear = a.front;
		}
		else
			a.rear = (a.rear + 1) % a.maxSize;
		

		a.front = (a.front + 1) % a.maxSize;
		
		
	}

	sum = 0;
	j = a.front;
	do
	{
		sum += a.base[j];
		cout << a.base[j] << "	" << "j:" << j << endl;
		j = (j + 1) % a.maxSize;
	} while ((j + 1) % a.maxSize != a.front);

	return sum;
}

/**********

12【题目】设A=(a1,…,am)和B=(b1,…,bn)均为有序顺序表,

A’和B’分别为A和B中除去最大共同前缀后的子表(例如,
A=(x,y,y,z,x,z),B=(x,y,y,z,y,x,x,z),则两者中最大
的共同前缀为(x,y,y,z), 在两表中除去最大共同前缀后
的子表分别为A’=(x,z)和B’=(y,x,x,z))。若A’=B’=空表,
则A=B;若A’=空表,而B’≠ 空表,或者两者均不为空表,
且A’的首元小于B’的首元,则A<B;否则A>B。试写一个比
较A和B大小的算法。(注意:在算法中,不要破坏原表A
和B,也不一定先求得A’和B’才进行比较)。
顺序表类型定义如下:

typedef struct {
  ElemType *elem;
  int       length;
  int       size;
  int       increment;
} SqList;

**********/

char Compare(SqList A, SqList B)
/* 比较顺序表A和B,      */
/*   返回'<', 若A<B;    */
/*       '=', 若A=B;    */
/*       '>', 若A>B     */
{
   int i;
    if (A.elem[0]!=B.elem[0])
    {
        if (A.elem[0] < B.elem[0])
            return '<';
        else if (A.elem[0] > B.elem[0] )
            return '>';
        else if (A.length == B.length)
            return '=';
    }
    
    for (i=0;i<A.length;i++)
    {
        if (A.elem[i] == B.elem[i])
            continue;
        else 
            break;
    }
    
     if (i == A.length)
    {
        if (i == B.length)
            return '=';
        else 
            return '<';
    }
    else
    {
        if (i+1 == B.length)
            return '>';
        else if (A.length < B.length)
            return '<';
        else if (A.length > B.length)
            return '>';
        else if (A.elem[i+1] < B.elem[i+1])
            return '<';
        else 
            return '>';
    }
}

/**********

13 【题目】试写一算法,实现顺序表的就地逆置,

即利用原表的存储空间将线性表(a1,a2,…,an)
逆置为(an,an-1,…,a1)。
顺序表类型定义如下:

typedef struct {
  ElemType *elem;
  int       length;
  int       size;
  int       increment;
} SqList;
**********/
void Inverse(SqList &L)
{
    for (i=0;i<L.length/2;i++)
	{
		ElemType t;
		t = L.elem[i];
		L.elem[i] = L.elem[L.length - i - 1];
		L.elem[L.length - i - 1] = t;
	}
}

/**********

14【题目】试对一元稀疏多项式Pn(x)采用存储量同多项式

项数m成正比的顺序存储结构,编写求Pn(x0)的算法(x0
为给定值)。

一元稀疏多项式的顺序存储结构:

typedef struct {
  int  coef;  // 系数
  int   exp;  // 指数
} Term;

typedef struct {
  Term  *elem;   // 存储空间基址
  int    length; // 长度(项数)
} Poly;
**********/
float Evaluate(Poly P, float x)
/* P.elem[i].coef 存放ai,                        */
/* P.elem[i].exp存放ei (i=1,2,...,m)              */
/* 本算法计算并返回多项式的值。不判别溢出。       */
/* 入口时要求0≤e1<e2<...<em,算法内不对此再作验证 */
{
    int i, j;
	float sum = 0;
	float t;
	for ( i = 0; i < P.length; i++)
	{
		t = x;
		if (P.elem[i].exp == 0)
		{
			t = 1.0;
		}
		else
		{
			for ( j = 1; j < P.elem[i].exp; j++)
				t *= x;
		}
		sum += (float)P.elem[i].coef*t;
	}
	return sum;
}

/**********

15 【题目】假设有两个集合A和B分别用两个线性表LA和LB

表示(即:线性表中的数据元素即为集合中的成员),
试写一算法,求并集 A = A ∪ B A=A∪B AAB
顺序表类型定义如下

typedef struct {
  ElemType *elem;     // 存储空间的基址
  int length;    // 当前长度
  int size;      // 存储容量 
  int increment; // 空间不够增加空间大小
} SqList;  // 顺序表

//可调用顺序表的以下接口函数:   
Status InitList_Sq(SqList &L, int size, int inc); // 初始化顺序表L
int ListLength_Sq(SqList L);  // 返回顺序表L中元素个数
Status GetElem_Sq(SqList L, int i, ElemType &e); 
// 用e返回顺序表L中第i个元素的值
int Search_Sq(SqList L, ElemType e); 
// 在顺序表L顺序查找元素e,成功时返回该元素在表中第一次出现的位置,否则返回-1
Status Append_Sq(SqList &L, ElemType e);  // 在顺序表L表尾添加元素e
**********/
void Union(SqList &La, SqList Lb)
{
    if (La.elem == NULL)
        if (Lb.elem == NULL)
            La.elem == NULL;
        else
            La.elem = Lb.elem;
    else
    {
       int la = ListLength_Sq(La);
        int lb = ListLength_Sq(Lb);
    
        int i,j;
        for (i = 1;i <= lb;i++)
        {
            GetElem_Sq(Lb,i,j);
            if (Search_Sq(La,j) != -1)
                continue;
            else
            {
                //if (La.length+1 == La.size)
                Append_Sq(La,j);
            }    
        }
    }             
     
}

求出并集,要放到第一个表里!!

/**********

16【题目】试写一算法,实现链栈的判空操作。

链栈的类型定义为:

typedef struct LSNode {
  ElemType data;       // 数据域
  struct LSNode *next; // 指针域
} LSNode, *LStack;    // 结点和链栈类型
***********/
Status StackEmpty_L(LStack S)
/* 对链栈S判空。若S是空栈,则返回TRUE;否则返回FALSE */
{
    if (S == NULL)
        return TRUE;
    else
        return  FALSE;
}

/**********

17 【题目】试写一算法,实现链栈的取栈顶元素操作。

链栈的类型定义为:

typedef struct LSNode {
  ElemType data;       // 数据域
  struct LSNode *next; // 指针域
} LSNode, *LStack;    // 结点和链栈类型
***********/
Status GetTop_L(LStack S, ElemType &e) 
/* 取链栈S的栈顶元素到e,并返回OK; */
/* 若S是空栈,则失败,返回ERROR。  */
{
    if (S == NULL)
        return ERROR;
    else
    {
        e = S->deta;
        return  OK;
    }
}

/**********

18 【题目】试写一算法,实现链队列的判空操作。

链队列的类型定义为:

typedef struct LQNode {     
  ElemType  data;  
  struct LQNode  *next;  
} LQNode, *QueuePtr; // 结点和结点指针类型

typedef struct {     
  QueuePtr  front;  // 队头指针
  QueuePtr  rear;   // 队尾指针
} LQueue;  // 链队列类型


Status QueueEmpty_LQ(LQueue Q)
/* 判定链队列Q是否为空队列。           */
/* 若Q是空队列,则返回TRUE,否则FALSE。*/
{
   if (Q.front->next == Q.rear)
    return TRUE;
    else
    return FALSE;
}

/**********

19 【题目】试写一算法,实现链队列的求队列长度操作。

链队列的类型定义为:

typedef struct LQNode {     
  ElemType  data;  
  struct LQNode  *next;  
} LQNode, *QueuePtr; // 结点和结点指针类型
typedef struct {     
  QueuePtr  front;  // 队头指针
  QueuePtr  rear;   // 队尾指针
} LQueue;  // 链队列类型
***********/
int QueueLength_LQ(LQueue Q)
/* 求链队列Q的长度并返回其值 */
{
    int l = 0;
    QueuePtr p = Q.front;
    while(p->next != Q.rear)
    {
        l++;
        p = p->next;
    }
    return l;
}

/**********

20【题目】(PE68) 假设以带头结点的循环链表表示队列,并且

只设一个指针指向队尾元素结点(注意不设头指针),
试编写相应的队列初始化、入队列和出队列的算法。
带头结点循环链队列CLQueue的类型定义为:

typedef struct LQNode {
  ElemType data;
  struct LQNode *next;
} LQNode, *CLQueue;
**********/
Status InitCLQueue(CLQueue &rear) // 初始化空队列
{ 

    if (NULL == (rear = (CLQueue) malloc (sizeof(CLQueue))))
        return OVERFLOW;
    else
    {
        rear->next = NULL;
        //L->next = rear;
        return OK;
    }
}

Status EnCLQueue(CLQueue &rear, ElemType x) // 入队
{ 
    CLQueue p;
    //q = rear->next;
   if (NULL == (p = (LQNode*) malloc (sizeof(LQNode))))
        return OVERFLOW;
    p->data = x;
    
    //printf("%c\n",x);
    //printf("\n");
        
    p->next = rear->next;
    
    rear->next = p;
    rear = p;
    //rear->next->data;
    return OK;
}

Status DeCLQueue(CLQueue &rear, ElemType &x) // 出队
{ 
CLQueue p = rear;

    if (rear->next == NULL)
        return ERROR;
    else
    {
        while (p->next != rear)
            p = p->next;
        x = rear->data;
        rear = rear->next;
        p->next = rear;
        return OK;
    }
}

注意:
在使用malloc函数来分派内存的时候,前面括号里是该类型的指针类型,后面括号才是该类型
(隔了一段时间就容易忘……2333……)

在自己电脑的测试代码及数据

#include <iostream>
#include <cstdlib>

using namespace std;

#define TRUE 1
#define FALSE 0

#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef int Status;

#define ElemType char 

typedef struct LQNode {
	ElemType data;
	struct LQNode *next;
} LQNode, *CLQueue;


Status InitCLQueue(CLQueue &rear) // 初始化空队列
{
	if (NULL == (rear = (CLQueue)malloc(sizeof(CLQueue))))
		return OVERFLOW;
	else
	{
		rear->next = rear;
		//L->next = rear;
		return OK;
	}
}


Status EnCLQueue(CLQueue &rear, ElemType x) // 入队
{
	CLQueue p;
	if (NULL == (p = (CLQueue)malloc(sizeof(CLQueue))))
		return OVERFLOW;
	p->data = x;
	p->next = rear->next;
	rear->next = p;
	rear = p;
	return OK;
}


Status DeCLQueue(CLQueue &rear, ElemType &x) // 出队
{
	CLQueue p = rear->next;
	CLQueue q = p->next;

	if (rear->next == rear)
		return ERROR;
	else
	{
		x = q->data;
		p->next = q->next;
		return OK;
	}
}

//定义一个打印函数
void printCLquene(CLQueue rear)
{
	CLQueue p = rear->next;
	p = p->next;
	while (p != rear->next)
	{
		printf("%c",p->data);
		p = p->next;
	}
	cout << endl;
}

//输入函数
void input(CLQueue &rear,int n)
{
	char c;
	CLQueue q,p;

	
	p = rear->next;
	for (int i = 0; i < n; i++)
	{
		cout << "输入data" << endl;
		cin >> c;

		q = (CLQueue)malloc(sizeof(CLQueue));
		q->data = c;

		
		rear->next = q;
		rear = q;
		rear->next = p;
	}
}

int main()
{
	//定义一个循环列表
	CLQueue rear, p,q;
	初始化
	InitCLQueue(rear);

	input(rear, 3);
	
	printCLquene(rear);

	//入队操作
	ElemType e;
	e = 'M';
	EnCLQueue(rear,e);

	printCLquene(rear);

	return 0;
}  

/**********

21 【题目】试写一算法,实现带头结点单链表的判空操作。

单链表的类型定义为:

typedef struct LNode {     
  ElemType  data;  
  struct LNode  *next;  
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status ListEmpty_L(LinkList L)
/* 判定带头结点单链表L是否为空链表。   */
/* 若L是空链表,则返回TRUE,否则FALSE。*/
{
    if (L->next == NULL)
        return TRUE;
    else
        return FALSE;
}

/**********

22 【题目】试写一算法,实现带头结点单链表的销毁操作。

单链表的类型定义为:

typedef struct LNode {     
  ElemType  data;  
  struct LNode  *next;  
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status DestroyList_L(LinkList &L)
/* 销毁带头结点单链表L,并返回OK。*/
{
    LinkList p,q;
    LinkList a,b,c;
    p = L->next;
    if (p == NULL)
    {
        free(L);
        return OK;  
    }
    while (p != NULL)
    {
        q = p;
        p = p->next;
        free(q);
    }
    
    free(L);
    return OK;
}

/**********

23 【题目】试写一算法,实现带头结点单链表的清空操作。

单链表的类型定义为:

typedef struct LNode {     
  ElemType  data;  
  struct LNode  *next;  
} LNode, *LinkList; // 结点和结点指针类型
***********/
Status ClearList_L(LinkList &L)
/* 将带头结点单链表L置为空表,并返回OK。*/
/* 若L不是带头结点单链表,则返回ERROR。 */
{
     if (NULL == L)
        return  ERROR;
   LinkList p,q;
    LinkList a,b,c;
    p = L->next;
    if (p == NULL)
        return OK;
    while (p != NULL)
    {
        q = p;
        p = p->next;
        free(q);
    }
    
    L->next = NULL;
    return OK;
}

/**********

24 【题目】试写一算法,实现带头结点单链表的求表长度操作。

单链表的类型定义为:

typedef struct LNode {     
  ElemType  data;  
  struct LNode  *next;  
} LNode, *LinkList; // 结点和结点指针类型
***********/
int ListLength_L(LinkList L)
/* 求带头结点单链表L的长度,并返回长度值。*/
/* 若L不是带头结点单链表,则返回-1。      */
{
    if (NULL == L)
        return -1;
   LinkList p;
    p = L->next;
    
    int num = 0;
    while (p != NULL)
    {
        p = p->next;
        num++;
    }
    return num;
}

/**********

25(PE82)【题目】试写一算法,在带头结点单链表L插入第i元素e。

带头结点单链表的类型定义为:

typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;
**********/
Status Insert_L(LinkList L, int i, ElemType e)
/* 在带头结点单链表L插入第i元素e,并返回OK。*/
/* 若参数不合理,则返回ERROR。              */
{
    LinkList p = L;
    if (NULL == p || i <1)
        return ERROR;
    
    int num = 1;
    while (p->next != NULL && num<i)
    {
        p = p->next;
        num++;
    }
    if (num <i)
        return ERROR;
    LinkList m;
    m = (LinkList) malloc (sizeof(LNode));
    
    m->next = p->next;
    p->next = m;
    m->data = e;
    
    return OK;
}

测试代码

#include <iostream>
#include <cstdlib>

using namespace std;

#define TRUE 1
#define FALSE 0

#define OK 1
#define ERROR 0
#define OVERFLOW -1

typedef int Status;

#define ElemType char 

typedef struct LNode {
	ElemType      data;
	struct LNode *next;
} LNode, *LinkList;


Status Insert_L(LinkList L, int i, ElemType e)
/* 在带头结点单链表L插入第i元素e,并返回OK。*/
/* 若参数不合理,则返回ERROR。              */
{
	LinkList p = L;
	if (NULL == p || i <1)
		return ERROR;

	int num = 1;
	while (p->next != NULL && num<i)
	{
		p = p->next;
		num++;
	}
	if (num <i)
		return ERROR;
	LinkList m;
	m = (LinkList)malloc(sizeof(LinkList));

	m->next = p->next;
	p->next = m;
	m->data = e;

	return OK;
}

//初始化带头结点的单链表函数
void InitLinkList(LinkList &L)
{
	LinkList q;
	
	char c[] = {"abcdefg"};
	
	q = L;
	//q->next = L->next;

	for (int i = 0; i < 7; i++)
	{
		LinkList p = (LinkList)malloc(sizeof(LinkList));
		p->data = c[i];
		p->next = q->next;
		q->next = p;
		q = q->next;
	}
	//L = q;
}


//定义打印函数
void printLinkLIst(LinkList &L)
{
	LinkList p;
	p = L->next;

	while (p != NULL)
	{
		cout << p->data;
		p = p->next;
	}
	cout << endl;
}

int main()
{
	//定义一个带头结点的单链表
	//L3 = ( abcdefg)
	LinkList L = (LinkList)malloc(sizeof(LinkList));
	L->next = NULL;

	InitLinkList(L);

	printLinkLIst(L);

	Insert_L(L,2,'*');

	printLinkLIst(L);

	return 0;
}  

/**********

26(84)【题目】试写一算法,在带头结点单链表删除第i元素到e。

带头结点单链表的类型定义为:

typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;
**********/
Status Delete_L(LinkList L, int i, ElemType &e)
/* 在带头结点单链表L删除第i元素到e,并返回OK。*/
/* 若参数不合理,则返回ERROR。                */
{
    LinkList p = L;
    LinkList q ;
    if (NULL == p || i <1)
        return ERROR;
    
    int num = 0;
    while (p->next != NULL && num<i)
    {
        q = p;
        p = p->next;
        num++;
    }
    
    if (i > num)
        return ERROR;
    
        LinkList m = p;
        e = m->data;
        q->next = m->next;
   
     //free(m);
     return OK;
}

/**********

27 【题目】试写一算法,在带头结点单链表的第i元素起的

所有元素从链表移除,并构成一个带头结点的新链表。
带头结点单链表的类型定义为:

typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;
**********/
Status Split_L(LinkList L, LinkList &Li, int i)
/* 在带头结点单链表L的第i元素起的所有元素 */
/* 移除,并构成带头结点链表Li,返回OK。   */
/* 若参数不合理,则Li为NULL,返回ERROR。  */
{
     LinkList p = L;
  LinkList q;
  q = (LinkList) malloc (sizeof(LNode));
  Li = (LinkList) malloc (sizeof(LNode));
    if (NULL == p || i <1)
    {
        Li = NULL;
        return ERROR;
    }
    
    int num = 0;
    while (p->next != NULL && num<i)
    {
        q = p;
        p = p->next;
        num++;
    }
    if (i > num)
    {
        Li = NULL;
        return ERROR;
    }
        
     LinkList p1 = p;
     LinkList p2 = Li;
     
     while (p1 != NULL)
     {
        q->next = p1->next;
        
        p1->next = p2->next;
        p2->next = p1;
        
        p1 = q->next;
        p2 = p2->next;
     }
     
     return OK;
}

注意!!别忘了出错的时候把Li置为空

/**********

28【题目】试写一算法,在带头结点单链表删除第i元素

起的所有元素。
带头结点单链表的类型定义为:

typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;
**********/
Status Cut_L(LinkList L, int i)
/* 在带头结点单链表L删除第i元素起的所有元素,并返回OK。*/
/* 若参数不合理,则返回ERROR。                         */
{
     LinkList p = L;
    if (NULL == p || i <1)
        return ERROR;
    
    int num = 0;
    while (p->next != NULL )
    {
        p = p->next;
        num++;
    }
    
    if (i > num)
        return ERROR;
        
     LinkList m = L;
     for(int k=0;k<i-1;k++)
        m = m->next;
    
    m->next=null;
      return OK;
}

/**********

29【题目】试写一算法,删除带头结点单链表中所有值

为x的元素,并释放被删结点空间。
单链表类型定义如下:

typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;
**********/
Status DeleteX_L(LinkList L, ElemType x)
/* 删除带头结点单链表L中所有值为x的元素,      */
/* 并释放被删结点空间,返回实际删除的元素个数。*/
{
    LinkList p = L;
    if (NULL == p->next)
        return ERROR;
    
    int num = 0;
    LinkList m;
    while (p != NULL)
    {
        m = p;
        if (m->next->data == x)
        {
            m = m->next;
            p->next = m->next;
            free(m);
            num++;
        }
        p = p->next;
    }
    
    return num;
}

30【题目】试写一算法,删除带头结点单链表中所有值

小于x的元素,并释放被删结点空间。
单链表类型定义如下:

typedef struct LNode {
  ElemType      data;
  struct LNode *next;
} LNode, *LinkList;
******/
Status DeleteSome_L(LinkList L, ElemType x)
/* 删除带头结点单链表L中所有值小于x的元素,    */
/* 并释放被删结点空间,返回实际删除的元素个数。*/
{
     LinkList p = L;
    if (NULL == p->next)
        return ERROR;
    
    int num = 0,flag;
    LinkList m;
    while (p->next != NULL)
    {
        flag = 0; 
        if (p->next->data < x)
        {
            m = p->next;
            p->next = m->next;
            free(m);
            num++;
            flag = 1;
        }
        if (!flag)
            p = p->next;
    }
    
    return num;
}
  • 19
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值