单链表的操作

头结点:链表的第一个有效结点前面的结点,头结点并不存放有效数据,也就是数据域为空,加头结点的主要目的是为了方便链表的操作。

首节点:链表的第一个有效结点,结点包含数据域和指针域。

尾结点:尾结点的指针域为空。

头指针:指向头结点的指针变量,它存放了头结点的地址(在这里注意一下,指针变量存放的是地址,也就是说头指针存放的是头结点的地址,一般通过头指针对链表进行操作)。

具体实现如下:

#include<iostream>
using namespace std;
#define Status int
#define ElemType int
#define ERROR -1
#define OK 1

int i, j;

typedef struct LNode{             //结构体定义
 ElemType data;
 struct LNode *next;
}LNode, *LinkList;
LNode *p;
LNode *q;

void CreateList_L(LinkList &L, int n)           //创建一个链表
{
 cout << "输入链表的数据:";
 L = (LinkList)malloc(sizeof(LNode));
 L->next = NULL;                             //创建头结点
 int a[20];
 for (int i = 1; i <= n; i++)
 {
  cin >> a[i];
 }
 for (i = n; i > 0; i--)
 {
  p = (LinkList)malloc(sizeof(LNode));    //头插法插入数据
  p->data = a[i];
  p->next = L->next;
  L->next = p;
 }
}

Status LisInsert_L(LinkList &L, int i, ElemType e)
{
 LinkList s;                          //在链表的第i个元素之前插入新元素
 p = L; j = 0;
 while (p&&j < i - 1)
 {
  p = p->next;
  ++j;
 }
 if (!p || j>i - 1)
  return ERROR;
 s = (LinkList)malloc(sizeof(LNode));
 s->data = e;
 s->next = p->next;
 p->next = s;
 return OK;
}

Status ListDelete_L(LinkList &L, int i, ElemType &e)
{
 p = L; j = 0;
 while (p->next&&j < i - 1)                    //删除第i个元素
 {
  p = p->next; ++j;
 }
 if (!(p->next) || j>i - 1)
  return ERROR;
 q = p->next;
 p->next = q->next;
 e = q->data;
 free(q);
 return OK;  
}

int GetLength(LinkList &L)
{
 p = L->next; int length = 0;           //获得链表的长度
 while (p != NULL)
 {
  length++;
  p = p->next;
 }
 return length;
}

ElemType GetData(LinkList &L, ElemType &e, int i)
{
 p = L->next;                       //获得链表第i个元素的数据
 j = 1;
 while (p&&j < i)
 {
  p = p->next;
  ++j;
 }
 if (!p || j>i)
  return ERROR;
 e = p->data;
 return e;
}

ElemType fixData(LinkList &L, ElemType &e, int i)
{
 p = L->next;                      // 修改第i个元素
 j = 1;
 while (p&&j < i)
 {
  p = p->next;
  ++j;
 }
 if (!p || j>i)
  return ERROR;
 p->data = e;
 return e;
}

void show(LinkList &L)
{
 p = L->next;
 cout << "链表所存数据为:";
 while (p)
 {
  cout << p->data << ' ';
  p = p->next;
 }
 cout << endl;
}

int main()
{
 LinkList L;
 int x = 0;
 int n = 0;
 cout << "请输入链表的元素个数:";
 cin >> n;
 CreateList_L(L, n);
 show(L);
 cout << "请输入插入数据的位置:";
 cin >> n;
 cout << "请输入插入数据:";
 cin >> x;
 LisInsert_L(L, n, x);
 show(L);
 cout << "链表的长度为:" << GetLength(L) << endl;
 cout << "请输入元素序号,查询该元素数据:";
 cin >> n;
 cout << GetData(L, x, n) << endl;
 cout << "请输入元素序号,修改该元素数据:";
 cin >> n;
 cout << "请输入修改的元素数据:";
 cin >> x;
 fixData(L, x, n);
 show(L);
 cout << "请输入元素序号,删除该元素:";
 cin >> n;
 ListDelete_L(L, n, x);
 show(L);
 return 0;
}

上面实现的主要是单链表,另外还有双链表、循环链表、非循环链表等其他几种常见链表。双链表的特殊性表现在每个基本结点有两个指针域;循环链表的特性主要表现在,在循环链表中,通过任何一个结点可以找到其他所有结点。

posted @ 2016-11-28 20:57  ll7  阅读(175)  评论(0编辑  收藏  举报