第二章:线性表

来源:互联网 发布:mysql快照 编辑:程序博客网 时间:2024/05/01 18:44

对于线性表上的顺序存储结构实现的基本运算常用的一般是插入和删除。  以下是完整的代码:

 

#include <stdio.h>
#include "biao.h"

main()
{
 

void output(Seqlist *L); 
void insertlist(Seqlist *L,int x,int i );
void deletelist(Seqlist *L,int i);
void print(Seqlist *L);

 

 


 Seqlist    L;
 
 L.length=0;
 creatlist(&L);
  output(&L);

 printf("插入的一个值:/n");
 insertlist(&L,2,2);
 output(&L);

 printf("删除的一个值:/n");
 deletelist(&L,3);
 output(&L);
}

 

 

#ifndef biao

#define ListSize 10

typedef struct
{
 int data[ListSize];
 int length;
}Seqlist;

void creatlist(Seqlist *L);
void insertlist(Seqlist *,int x,int i);
void deletelist(Seqlist *,int i);
void output(Seqlist *);

 

#endif

 

 

 

#include <stdio.h>
#include "biao.h"
#include <malloc.h>
void insertlist(Seqlist * L,int x,int i)
{//将新结点x插入到L所指的顺序表的第i个结点ai的位置上。

 int j;
if(i>=1&&i<L->length)
{ for(j=L->length-1;j>=i-1;j--)//i-1其实就是ai所在的位置,因为c语言的下标是从0开始的,因此这里有点让人晕。
  L->data[j+1]=L->data[j];

 L->data[i-1]=x;
 L->length++;
}
}


void deletelist(Seqlist *L,int i)
{//从L所指的顺序表中删除第i个结点ai
 int j;

 for(j=i;j<=L->length-1;j++)
  L->data[j-1]=L->data[j];
 
    L->length--;
 
}

 

void output(Seqlist *L)
{
 int j;
 printf("该顺序表的所有值为:/n");

 for(j=0;j<L->length;j++)
 printf("%d, ",L->data[j]);
 printf("/n");
}

 

void creatlist(Seqlist *L)//初始化
{
  

 int i;

for(i=0;i<10;i++)
{ L-> data[L->length]=i;
  printf(" %d",i);
 L->length++;
}
}

以上例题是简单的实现了顺序存储结构的基本运算。

 

现在来说说线性表的链式存储结构实现的基本运算:

 

单链表基本运算:

 

 

 #ifndef biao


typedef struct node
{
 char data;
 struct node *next;

}listnode;
typedef listnode *linklist;
void Initcity(linklist *head)  ;
 linklist cteatlistR(void);
 linklist cteatlistF();
 listnode *getnode(linklist head,int i);
 listnode *Locatenode(linklist head,int key);
 void insertlist(linklist head,int x,int i);
 void deletelist(linklist head,int i);
 void output(linklist head);
#endif

 

 

#include <stdio.h>
#include "biao.h"
#include <malloc.h>
#include <stdlib.h> 

/*
void Initcity(linklist *head)       
{  
   head=(listnode *)malloc(sizeof(listnode));
   head->next=NULL;
}
*/


//头插法建表
linklist cteatlistF(void)
{//返回单链表的头指针。

 char ch;
 linklist head;
 listnode *s;//工作指针
 head=NULL;//链表开始为空。
 ch=getchar();
 while(ch!='/n')
 {
  s=(listnode *)malloc(sizeof(listnode));//生成新结点。
  s->data=ch;
  s->next=head;
  head=s;
  ch=getchar();
 }
 return head;

}


//尾插法建表(一)
 linklist cteatlistR(void)
{
 char ch;
 linklist head;
 listnode *s,*r;
 head=NULL;r=NULL; //链表初值为空,尾指针初值为空。
 while((ch=getchar())!='/n')
 {
  s=(listnode *)malloc(sizeof(listnode));//生成新结点。
  s->data=ch;
  if(head==NULL)
   head=s;
  else
   r->next=s;
  r=s;

 }
 if(r!=NULL)
  r->next=NULL;
 return head;

}
/*//尾插法建表(二)
linklist cteatlistR()
{
 char ch;
 linklist head=(linklist)malloc(sizeof(listnode));
 listnode *s,*r;
 r=head;
 while(ch=getchar()!='/n')
 {
  s=(listnode *)malloc(sizeof(listnode));//生成新结点。
  s->data=ch;
  r->next=s;
  r=s;

 }
 r->next=NULL;
 return head;
} */

 

//按序号查找

listnode *getnode(linklist head,int i)
{//在带头结点的单链表head中查找第i个结点,若找到(0<=i<=n),则返回该结点的存储位置,否则返回 null。

 int j;
 listnode *p;
 p=head;
 j=0;//从头结点开始扫描。
 while(p->next&&j<i)//顺时针向后扫描,直到p->next为null或j=i为止
 {
  p=p->next;
  j++;
 }
 if(j==i)
  return p;
 else
  return  NULL;

 
}

//按值查找

listnode *Locatenode(linklist head,int key)
{//在带头结点的单链表head中查找其值尾key的结点。

 listnode *p=head->next;
 while(p&&p->data!=key)
 {
 p=p->next;
 }
 return p;
 
}

//插入运算

void insertlist(linklist head,int x,int i)
{//将值为x的新结点插入到带头结点的单链表head的第i个的结点的位置上。
 listnode *p,*s;
 p=getnode(head,i-1);

// if(p==NULL)
//  error(" position error");
  
 s=(listnode*)malloc(sizeof(listnode));
 s->data=x;
 s->next=p->next;
 p->next=s;
}

//删除运算

void deletelist(linklist head,int i)
{//删除带头结点的单链表head上的第i个结点
 listnode *p,*r;
  p=getnode(head,i-1);

 //if(p==NULL||p->next==NULL)
 // error("pssition error");

 r=p->next;//令r指向被删结点ai。
 p->next=r->next;
 free(r);//释放结点ai,将所占的空间归还给存储池。
 
}

 

 void output(linklist head )
    {
         listnode *p;
 p=head;
 if(p==NULL)
  printf("目前单链表为空/n");
 else
 {
  printf("下面输出目前链表里所有结点:/n");
  while(p!=NULL)
  {
   printf("%d ",p->data);
   p=p->next;
  }
  printf("/n");

    }


 }

 

 

#include <stdio.h>
#include "biao.h"


void main()
{

  linklist cteatlistR(void);
 linklist cteatlistF();
 listnode *getnode(linklist head,int i);
 listnode *Locatenode(linklist head,int key);
 void insertlist(linklist head,int x,int i);
 void deletelist(linklist head,int i);
 void output(linklist head );

 linklist   head;


 head = cteatlistR();

 output(head);

// printf("按序号查找:");
// head=getnode(head,3);
 // output(head );

 

 printf("按值查找:");
 head=Locatenode(head,'d');
  output(head );

 printf("插入:");
 insertlist(head,'b',3);
  output(head );

 printf("删除:");
 deletelist(head,3);
  output(head );

}

 

以上例题是简单的实现了单链表的基本运算。

 

 

在这一章还谈了些循环链表和双链表的,在这我就不详细谈了。(呵呵,应该是没心情!等哪天想好了再说)

 

 

接下来说说顺序表和链表的比较:

(1)基于空间的考虑:

 

顺序表的存储空间是静态分配的,在程序执行前必须明确规定它的存储规模;

 

链表的存储空间是动态分配的,只要内存空间尚有空闲,就不会产生溢出。

 

(2)基于时间的考虑:

 

顺序表是由向量实现的。它是一种随机存取结构,对表中任一结点都可在o(1)时间内直接的存取;

 

链表中的结点,需从头指针起顺着链扫描才能取得。