线性表(总结2)

来源:互联网 发布:windows查看显卡 编辑:程序博客网 时间:2024/05/02 00:12

2.线性链表

      线性链表是由n个结点链结成的一个链表。结点包括两个域:存储数据元素信息的域称为数据域;存储直接后继存储位置的域称为指针域。指针域中存储的信息称为指针或链。数据元素之间的逻辑关系是由结点中的指针指示的。

      单链表可由头指针唯一确定,头指针指示链表中第一个结点的存储位置。

 

//----------------线性表的单链表存储结构----------------

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

 

      单链表的第一个结点之前附设一个结点,称为头结点。头结点的数据域可以不存储任何信息,也可以存储如线性表的长度等类的附加信息,头结点的指针域存储指向第一个结点的指针(即第一个元素结点的存储位置)。若线性表为空表,则头结点的指针域为空。

 

 

//----------------L为带头结点的单链表的头指针----------------

//----------------当第i个元素存在时,其值赋给e并返回----------------

Status GetElem_L(LinkList L, int i, ElemType &e){
 LNode *p = L->next;  //初始化,p指向第一个结点
 j = 1;
 while (p && j < i){
  p = p->next;
  ++j;
 }
 if (!p || j > i)
  return ERROR;
 e = p->data;
 return OK;

 

         插入操作的指针修改语句为:

 

 

       s -> next = p -> next;   p -> next = s;

       删除操作的描述语句为:

 

 

p - > next = p -> next -> next;

 

//----------------带头结点的单链表L中第i个位置之前插入元素e----------------

Status ListInsert_L(LinkList &L, int i, ElemType e){
 LNode *p = L;
 j = 0;
 while (p && j < i - 1){
  p = p -> next;
  ++j;
 }
 if (!p || j > i - 1)
  return ERROR;
 LNode *s = (LinkList)malloc(sizeof (LNode));
 s ->data = e;
 s ->next = p ->next;
 p ->next = s;
 return OK;
}

 

//----------------带头结点的单链表L中,删除第i个位置元素,并由e返回其值----------------

Status ListDelete_L(LinkList &L, int i, ElemType &e){
 LNode *p = L;
 j = 0;
 while (p ->next && j < i - 1){
  p = p ->next;
  ++j;
 }
 if (! p ->next || j > i - 1)
  return ERROR;
 LNode *q = p ->next;
 p ->next = q ->next;
 e = q ->data;
 free (q);
 return OK;
}

 

      两个算法的时间复杂度都是O(n)。单链表和顺序存储结构不同,它是一种动态结构。建立线性表的链式存储结构的过程就是一个动态生成链表的过程。

 

//----------------逆位序输入n个元素的值,建立带头结点的单链表L----------------

void CreateList_L(LinkList &L, int n){
 L = (LinkList) malloc (sizeof (LNode));
 L ->next = NULL;   //先建立一个带头结点的单链表
 LNode *p;
 for (int i = n; i > 0; --i){
  p = (LinkList) malloc (sizeof (LNode));
  scanf (&p ->data);
  p ->next = L ->next;
  L ->next = p;
 }
 return OK;
}

 

       逆序建立单链表算法的时间复杂度都是O(n)。

 

//----------------已知单链线性表La和Lb的元素按值非递减排列----------------

//----------------归并La和Lb得到新的单链线性表Lc,Lc的元素也按照非递减排列----------------

void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc){
 LNode *pa = La ->next;
 LNode *pb = Lb ->next;
 LNode *pc;
 Lc = pc = La;   //用La的头结点作为Lc的头结点
 while (pa && pb){
  if (pa ->data <= pb ->data){
   pc ->next = pa;
   pc = pa;
   pa = pa ->next;
  }
  else{
   pc ->next = pb;
   pc = pb;
   pb = pb ->next;
  }
 }
 pc ->next = pa ? pa : pb;
 free (Lb);  //释放Lb的头结点
}

 

      链表归并和顺序表归并的时间复杂度相同,但空间复杂度不同。在归并两个链表为一个链表的时候,不需要另建新表的结点空间。

      有时,也可借用一维数组来描述线性链表,这种描述方法便于在不设“指针”的高级程序设计语言中使用链表结构。这种用数组描述的链表称为静态链表。

//----------------线性表的静态单链表存储结构----------------

#define MAXSIZE 1000

typedef struct{

      ElemType data;

      int cur;

}component, SLinkList[MAXSIZE];

http://download.csdn.net/source/2179322