线性表

//顺序表类型定义
  #define ListSize 100 //表空间的大小可根据实际需要而定,这里假设为100
  typedef int DataType; //DataType的类型可根据实际情况而定,这里假设为int
  typedef struct {
      DataType data[ListSize];//向量data用于存放表结点
      int length;//当前的表长度
     }SeqList;
//顺序表上实现的基本运算
//1.表的初始化
   void InitList(SeqList *L)
     {\\顺序表的初始化即将表的长度置为0
            L->length=0;
    }

//2.求表长
    int ListLength(SeqList *L)
       { \\求表长只需返回L->length
          return L->length;
      }

//3.取表中第i个结点
  DataType GetNode(L,i)
      {\\取表中第i个结点只需返回和L->data[i-1]即可
          if (i<1||i> L->length-1)
                  Error("position error");
          return L->data[i-1];
       }
//5. 插入
void InsertList(SeqList *L,DataType x,int i)
     {//将新结点 x插入L所指的顺序表的第i个结点ai的位置上
       int j;
       if (i<1||i>L->length+1)
           Error("position error");//非法位置,退出运行
       if (L->length>=ListSize)
           Error("overflow");     //表空间溢出,退出运行
       for(j=L->length-1;j>=i-1;j--)
            L->data[j+1]=L->data[j];//结点后移
       L->data[i-1]=x;      //插入x
       L->Length++;        //表长加1
     }
//6. 删除
 void DeleteList(SeqList *L,int i)
      {//从L所指的顺序表中删除第i个结点ai
         int j;
        if(i<1||i>L->length)
           Error("position error"); //非法位置
        for(j=i;j<=L->length-1;j++)
           L->data[j-1]=L->data[j]; //结点前移
        L->length--;                //表长减小
       }

//单链表的运算
// 1、建立单链表
 //(1) 头插法建表
 // 具体算法实现
    LinkList CreatListF(void)
      {//返回单链表的头指针
          char ch;
          LinkList head;//头指针
          ListNode *s;  //工作指针
          head=NULL;    //链表开始为空
          ch=getchar(); //读入第1个字符
          while(ch!='\n'){
              s=(ListNode *)malloc(sizeof(ListNode));//生成新结点
              s->data=ch;   //将读入的数据放入新结点的数据域中
              s->next=head;
              head=s;
              ch=getchar();  //读入下一字符
            }
          return head;
       } 
//(2) 尾插法建表 
// 具体算法实现 
    LinkList CreatListR(void)
      {//返回单链表的头指针
          char ch;
          LinkList head;//头指针
          ListNode *s,*r;  //工作指针
          head=NULL;    //链表开始为空
          r=NULL;//尾指针初值为空
          ch=getchar(); //读入第1个字符
          while(ch!='\n'){
              s=(ListNode *)malloc(sizeof(ListNode));//生成新结点
              s->data=ch;   //将读入的数据放入新结点的数据域中
           if (head!=NULL)
               head=s;//新结点插入空表
           else
               r->next=s;//将新结点插到*r之后
              r=s;//尾指针指向新表尾
           ch=getchar();  //读入下一字符
         }//endwhile
        if (r!=NULL)
             r->next=NULL;//对于非空表,将尾结点指针域置空head=s;
         return head;
    } 
//(3) 尾插法建带头结点的单链表 
      ③尾插法建带头结点链表算法 
  LinkList CreatListR1(void)
      {//用尾插法建立带头结点的单链表
          char ch;
          LinkList head=(ListNode *)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;
       } 
//单链表的查找运算 
(1)按序号查找
   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或i=j为止
          p=p->next;
          j++;
        }
      if(i==j)
         return p;//找到了第i个结点
      else return NULL;//当i<0或i>0时,找不到第i个结点
     } 
//(2) 按值查找
 ListNode* LocateNode (LinkList head,DataType key)
      {//在带头结点的单链表head中查找其值为key的结点
        ListNode *p=head->next;//从开始结点比较。表非空,p初始值指向开始结点
        while(p&&p->data!=key)//直到p为NULL或p->data为key为止
             p=p->next;//扫描下一结点
         return p;//若p=NULL,则查找失败,否则p指向值为key的结点
       }
//3.插入运算 
void InsertList(LinkList head,DataType x,int i)
      {//将值为x的新结点插入到带头结点的单链表head的第i个结点的位置上
        ListNode *p;
        p=GetNode(head,i-1);//寻找第i-1个结点
        if (p==NULL)//i<1或i>n+1时插入位置i有错
           Error("position error");
        s=(ListNode *)malloc(sizeof(ListNode));
        s->data=x;s->next=p->next;p->next=s;
      }  
//4.删除运算
  void DeleteList(LinkList head,int i)
      {//删除带头结点的单链表head上的第i个结点
         ListNode *p,*r;
         p=GetNode(head,i-1);//找到第i-1个结点
         if (p==NULL||p->next==NULL)//i<1或i>n时,删除位置错
              Error("position error");//退出程序运行
         r=p->next;//使r指向被删除的结点ai
         p->next=r->next;//将ai从链上摘下
         free(r);//释放结点ai的空间给存储池
       } 
//1、循环链表
 LinkList Connect(LinkList A,LinkList B)
       {//假设A,B为非空循环链表的尾指针
          LinkList p=A->next;//①保存A表的头结点位置
          A->next=B->next->next;//②B表的开始结点链接到A表尾
          free(B->next);//③释放B表的头结点
          B->next=p;//④
          return B;//返回新循环链表的尾指针
    }
//1、双向链表(Double Linked List)
//2、双向链表的结点结构和形式描述
//①结点结构(见上图a)
      
//②形式描述 
    typedef struct dlistnode{
         DataType data;
         struct dlistnode *prior,*next;
      }DListNode;
    typedef DListNode *DLinkList;
    DLinkList head;
//①双链表的前插操作
 void DInsertBefore(DListNode *p,DataType x)
      {//在带头结点的双链表中,将值为x的新结点插入*p之前,设p≠NULL
        DListNode *s=malloc(sizeof(DListNode));//①
        s->data=x;//②
        s->prior=p->prior;//③
        s->next=p;//④
        p->prior->next=s;//⑤
        p->prior=s;//⑥
       }
//②双链表上删除结点*p自身的操作
 void DDeleteNode(DListNode *p)
      {//在带头结点的双链表中,删除结点*p,设*p为非终端结点
          p->prior->next=p->next;//①
          p->next->prior=p->prior;//②
          free(p);//③
      } 


 


  

 

你可能感兴趣的:(线性表)