单链表常用操作实现:linklist.h文件
linklist.c文件:
测试主函数:main.c
- /*
- linklist.h
- 时间:2012年3月6日 14:07:17
- 目的:练习C语言基础知识,实现单链表常用操作
- */
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #define TRUE 1
- #define FALSE 0
- #define OK 1
- #define ERROR 0
- #define INFEASIBLE -1
- #define OVERFLOW -2
-
- typedef int Status;
- typedef int ElemType;
-
- /*链表结点*/
- typedef struct LNode
- {
- ElemType data;
- struct LNode * next;
- } * LinkList, LNode;
-
- /*构造一个空的线性表L*/
- Status InitLinkList(LinkList *L);
-
- /*线性表L已存在,操作结果:销毁线性表L*/
- void DestroyList(LinkList L);
-
- /*置空线性表,释放出头节点之外的所有的节点*/
- void ClearList(LinkList L);
-
- /*判断链表是否为空*/
- Status ListEmpty(LinkList L);
-
- /*链表L已存在,返回L中数据元素个数*/
- int ListLength(LinkList L);
-
- /*获取链表L中第i个结点的值*/
- Status GetElem(LinkList L, int i, ElemType *e);
-
- /*创建包含n个结点的链表*/
- void CreateList(LinkList L, int n);
-
- /*在链表L中的第i个结点之前插入一个结点*/
- Status ListInsert(LinkList L, int i, ElemType e);
-
- /*删除链表L中第i个位置的节点,e保存节点data域的值*/
- Status ListDelete(LinkList L, int i, ElemType *e);
-
- Status compile(ElemType e1, ElemType e2);
-
- int LocateElem(LinkList L, ElemType e);
-
- /*
- 链表L,cur_e不是第一个结点,如果链表中存在cur_e结点,则用pur_e返回该结点前驱
- 并返回OK,否则返回INFEASIBLE
- */
- Status PriorElem(LinkList L, ElemType cur_e, ElemType *pur_e);
-
- Status NextElem(LinkList L, ElemType cur_e, ElemType *next_e);
-
- Status ListTransver(LinkList L);
- #include "linklist.h"
- /*构造一个空的线性表L*/
- Status InitLinkList(LinkList *L)
- {
- //生成头结点
- *L = (LinkList)malloc(sizeof(LNode));
- if (!(*L))
- {
- return ERROR;
- }
- (*L)->next = NULL;
- return OK;
- }
- /*创建包含n个结点的链表,从表头插入数据*/
- void CreateList(LinkList L, int n)
- {
- int i;
- LinkList p;
- for (i = n; i > 0; --i)
- {
- p = (LinkList)malloc(sizeof(LNode));
- p->data = i;
- p->next = L->next;
- L->next = p;
- }
- }
- /*创建包含n个结点的链表,在表尾插入数据*/
- void CreateList2(LinkList L, int n)
- {
- //链表为空,L为头结点指针
- int i;
- LinkList p = L, s;
- for (i = 1; i <= n; i++)
- {
- s = (LinkList)malloc(sizeof(LNode));
- s->data = i;
- p->next = s;
- p = s;
- }
- p->next = NULL; //最后将最后插入元素的next域指向NULL
- }
- /*线性表L已存在,操作结果:销毁线性表L*/
- void DestroyList(LinkList L)
- {
- LinkList q;
- while (L)
- {
- q = L->next;
- free(L);
- L = q;
- }
- }
- /*置空线性表,释放出头节点之外的所有的节点*/
- void ClearList(LinkList L)
- {
- LinkList q = L->next, p;
- while (q)
- {
- p = q->next; // p = q;
- free(q); // q = q->next;
- q = p; // free(p);
- }
- L->next = NULL;
- }
- /*判断链表是否为空*/
- Status ListEmpty(LinkList L)
- {
- if (L->next)
- return FALSE;
- else
- return TRUE;
- }
- /*链表L已存在,返回L中数据元素个数*/
- int ListLength(LinkList L)
- {
- LinkList q = L->next; //q指向第一个结点
- int i = 0;
- while (q)
- {
- i++;
- q = q->next;
- }
- return i;
- }
- /*获取链表L中第i个结点的值*/
- Status GetElem(LinkList L, int i, ElemType *e)
- {
- int j = 1;
- LinkList q = L->next;
- while (q && j < i)
- {
- q = q->next; //q指向i个结点
- j++;
- }
- if (!q || j > i)
- {
- return ERROR;
- }
- *e = q->data;
- return OK;
- }
- /*在链表L中的第i个结点之前插入一个结点*/
- Status ListInsert(LinkList L, int i, ElemType e)
- {
- LinkList p = L, s;
- int j = 1;
- while (p && j < i)
- {
- p = p->next; //p指向第i个位置前一个结点
- j++;
- }
- if (!p || j > i)
- return ERROR;
- s = (LinkList)malloc(sizeof(LNode));
- s->data = e; //
- s->next = p->next; //
- p->next=s;
- return OK;
- }
- /*删除链表L中第i个位置的节点,并返回节点data域的值*/
- Status ListDelete(LinkList L, int i, ElemType *e)
- {
- LinkList p = L, q;
- int j = 1;
- while (p && j < i)
- {
- p = p->next; //p指向第i个元素的前一个元素
- j++;
- }
- if (!p || j > i)
- return ERROR;
- q = p->next; //q指向第i个元素
- p->next = q->next;
- *e = q->data;
- free(q);
-
- return OK;
- }
- Status compile(ElemType e1, ElemType e2)
- {
- if (e1 > e2)
- return OK;
- else
- return FALSE;
- }
- int LocateElem(LinkList L, ElemType e)
- {
- int i = 0;
- LinkList p = L->next;
- while (p)
- {
- i++;
- if (compile(p->data, e))
- return i;
- p = p->next;
- }
- return 0;
- }
- /*
- 链表L,cur_e不是第一个结点,如果链表中存在cur_e结点,则用pur_e返回该结点前驱
- 并返回OK,否则返回INFEASIBLE
- */
- Status PriorElem(LinkList L, ElemType cur_e, ElemType *pur_e)
- {
- LinkList p = L->next, q; //p指向第一个结点
- while(p->next) //p的下一个结点不为空
- {
- q = p->next; //q指向p的下一个结点,
- if (q->data == cur_e) //如果p的下一个结点值与cur_e相等
- {
- //*pur_e = (ElemType *)malloc(sizeof(ElemType));
- *pur_e = p->data; //pur_e存放p的值
- return OK;
- }
- p = q; //
- }
- return INFEASIBLE;
- }
- Status NextElem(LinkList L, ElemType cur_e, ElemType *next_e)
- {
- LinkList p = L->next;
- while (p->next)
- {
- if (p->data == cur_e)
- {
- *next_e = p->next->data;
- return OK;
- }
- p = p->next;
- }
- return INFEASIBLE;
- }
- /*对链表结点数据域排序,由大到小输出*/
- void ListSort(LinkList L)
- {
- int i, j, tmp, len = ListLength(L);
- LinkList p, q;
- for (i = 0, p = L->next; i < len - 1; i++, p = p->next)
- {
- for (j = 0, q = L->next; j < len - i - 1; j++, q = q->next)
- {
- if (q->data > q->next->data)
- {
- tmp = q->data;
- q->data = q->next->data;
- q->next->data = tmp;
- }
- }
- }
- }
- Status ListTransver(LinkList L)
- {
- LinkList p = L->next; //p指向第一个有效结点
- while (NULL != p)
- {
- printf("%d ", p->data);
- p = p->next;
- }
- printf("\n");
- return OK;
- }
测试主函数:main.c
- #include "linklist.c"
- int main()
- {
- //LinkList L = (LinkList)malloc(sizeof(LNode));
- LinkList L;
- ElemType e;
- printf("初始化链表:-->");
- if(InitLinkList(&L))
- {
- printf("链表初始化成功!\n");
- }
- /*----------------------------*/
- printf("创建链表:\n");
- int n;
- printf("-->输入链表结点数量: ");
- scanf("%d", &n);
- CreateList(L, n);
- printf("-->创建%d个结点链表为: ", n);
- ListTransver(L);
- printf("-->链表长度为: %d\n", ListLength(L));
- /*----------------------------*/
- printf("链表是否为空: ");
- if (FALSE == ListEmpty(L))
- printf("非空\n");
- else
- printf("空\n");
- //-----------------------------
- printf("释放链表中除头结点之外的所有结点: \n");
- ClearList(L);
- printf("-->链表是否为空: ");
- if (FALSE == ListEmpty(L))
- printf("非空\n");
- else
- printf("空\n");
- printf("-->链表长度为: %d\n", ListLength(L));
- //----------------------------------------
- printf("创建新链表:\n");
- printf("-->输入链表结点数量: ");
- scanf("%d", &n);
- CreateList2(L, n);
- printf("-->创建%d个结点链表为: ", n);
- ListTransver(L);
- printf("-->链表长度: %d\n", ListLength(L));
- //在第3个结点之前插入结点
- printf("在第3个结点之前插入结点: \n");
- ListInsert(L, 3, 6);
- printf("-->插入新结点后: ");
- ListTransver(L);
- //将链表数据域按从大到小排序
- printf("-->链表数据域按从大到小排序: \n");
- printf("排序前: ");
- ListTransver(L);
- ListSort(L);
- printf("排序后: ");
- ListTransver(L);
-
- //获取第3个结点值
- printf("获取第4个结点值: \n");
- GetElem(L, 4, &e);
- printf("-->第3个结点的值为: %d\n", e);
- //删除第4个结点的值
- printf("删除第3个结点的值:\n");
- printf("删除前链表: ");
- ListTransver(L);
- ListDelete(L, 3, &e);
- printf("-->第3个结点的值为: %d\n", e);
- printf("删除后链表: ");
- ListTransver(L);
- //获取指定结点前驱
-
- //e = (ElemType *)malloc(sizeof(ElemType));
- printf("获取值为5的结点的前驱: \n");
- if (PriorElem(L, 5, &e) == OK)
- {
- printf("-->该结点有前驱,前驱值为: %d\n", e);
- }
- else
- {
- printf("-->不存在值为5的结点的前驱\n");
- }
- //获取指定结点后驱
- printf("获取值为5的结点的后驱: \n");
- if (NextElem(L, 5, &e) == OK)
- {
- printf("-->该结点有后驱,前驱值为: %d\n", e);
- }
- else
- {
- printf("-->不存在值为5的结点的后驱\n");
- }
- //free(e);
- //释放整个链表
- DestroyList(L);
- //ListTransver(L);
- return OK;
- }